From c18cd1c47bdc9bbdab74c9080b3ba12501e53514 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 30 Jun 2025 17:23:35 -0700 Subject: [PATCH 01/19] added custom image, not to spec && updated trinket svg --- docs/boards.md | 6 + docs/boards/SUMMARY.md | 1 + docs/boards/atisa-menorah.md | 11 + docs/boards/misc.md | 6 + docs/projects.md | 7 +- docs/projects/SUMMARY.md | 5 +- docs/static/libs/atisa-menorah.png | Bin 0 -> 9919 bytes .../board.svg | 182 +- .../board.svg | 15597 ++++------------ .../board.svg | 898 +- libs/adafruit-neotrellis-m4-express/board.svg | 69 +- libs/adafruit-trinket-m0/board.svg | 2 - libs/adafruit-trinket-m0/boardhd.svg | 18 - .../BreadboardViewGraphic_Template.svg | 297 + libs/atisa-menorah/README.md | 18 + libs/atisa-menorah/board.json | 29 + libs/atisa-menorah/board.svg | 70 + libs/atisa-menorah/config.ts | 3 + libs/atisa-menorah/device.d.ts | 112 + libs/atisa-menorah/pxt.json | 40 + libs/brain-nrf52840/board.svg | 8 +- libs/espressif-esp32-devkit-c/board.svg | 65 +- libs/machachi/board.svg | 8 +- libs/xinabox-cc03/board.svg | 210 +- libs/xinabox-cs11/board.svg | 214 +- pxtarget.json | 1 + 26 files changed, 5519 insertions(+), 12358 deletions(-) create mode 100644 docs/boards/atisa-menorah.md create mode 100644 docs/static/libs/atisa-menorah.png create mode 100644 libs/atisa-menorah/BreadboardViewGraphic_Template.svg create mode 100644 libs/atisa-menorah/README.md create mode 100644 libs/atisa-menorah/board.json create mode 100644 libs/atisa-menorah/board.svg create mode 100644 libs/atisa-menorah/config.ts create mode 100644 libs/atisa-menorah/device.d.ts create mode 100644 libs/atisa-menorah/pxt.json diff --git a/docs/boards.md b/docs/boards.md index fcdf5c58..f1040bde 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -42,6 +42,12 @@ This editor supports various maker boards, based on SAMD21, SAMD51, NRF52. --- +* name: Atisa Menorah +* url: /boards/atisa-menorah +* imageUrl: /static/libs/atisa-menorah.png + +--- + * name: Add your board * url: /boards/add-a-new-board * imageUrl: /static/libs/bead-servo.jpg diff --git a/docs/boards/SUMMARY.md b/docs/boards/SUMMARY.md index b47ba483..43c276b9 100644 --- a/docs/boards/SUMMARY.md +++ b/docs/boards/SUMMARY.md @@ -12,6 +12,7 @@ * [Feather Bluefruit NRF52840](/boards/adafruit-feather-nrf52840-express) * [ItsyBitsy nrf52840 Express](/boards/adafruit-itsybitsy-nrf52840-express) * [Circuit Playground Bluefruit](/boards/adafruit-circuit-playground-bluefruit) + * [Atisa Menorah](/boards/atisa-menorah) * [SparkFun](/boards/sparkfun) * [RedBoard Turbo](/boards/sparkfun-redboard-turbo) * [LumiDrive](/boards/sparkfun-lumidrive) diff --git a/docs/boards/atisa-menorah.md b/docs/boards/atisa-menorah.md new file mode 100644 index 00000000..4fa67e73 --- /dev/null +++ b/docs/boards/atisa-menorah.md @@ -0,0 +1,11 @@ +# Adafruit Trinket M0 + +```sim +forever(function() { + +}) +``` + +```package +atisa-menorah +``` \ No newline at end of file diff --git a/docs/boards/misc.md b/docs/boards/misc.md index 28b34ab6..31eb6ddb 100644 --- a/docs/boards/misc.md +++ b/docs/boards/misc.md @@ -51,6 +51,12 @@ --- +* name: Atisa Menorah +* url: /boards/atisa-menorah +* cardType: template + +--- + * name: Add a new board * url: /boards/add-a-new-board * cardType: url diff --git a/docs/projects.md b/docs/projects.md index a78dc0fe..a4a765b0 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -1,3 +1,7 @@ + + + + # Projects ```codecard @@ -150,5 +154,4 @@ [LoRa](/projects/lora), [Power](/projects/power), [Bit Radio](/projects/radio), -[Boards](/boards) - +[Boards](/boards) \ No newline at end of file diff --git a/docs/projects/SUMMARY.md b/docs/projects/SUMMARY.md index 81c8040e..6a3d69f2 100644 --- a/docs/projects/SUMMARY.md +++ b/docs/projects/SUMMARY.md @@ -1,5 +1,6 @@ -# Projects + +# Projects * [Jacdac](/boards/jacdac) * [MSR Jacdac IoT Brain 48 (ESP32-S2)](/boards/jacdac-iot-s2) * [MSR Jacdac Brain RP2040 59](/boards/jacdac-brain-rp2040) @@ -40,6 +41,7 @@ * [StichKit](/boards/stitchkit) * [Bluebird](/boards/teknikio-bluebird) * [Brain NRF5840](/boards/brain-nrf52840) + * [Atisa Menorah](/boards/atisa-menorah) * [Add a new board](/boards/add-a-new-board) * [Digital IO](/projects/digital-io) * [Blinky](/projects/digital-io/blinky) @@ -98,4 +100,5 @@ * [Jacdac](/boards/jacdac) * [XinaBox](/boards/xinabox) * [Misc](/boards/misc) + * [Atisa Menorah](/boards/atisa-menorah) * [Add your board](/boards/add-a-new-board) diff --git a/docs/static/libs/atisa-menorah.png b/docs/static/libs/atisa-menorah.png new file mode 100644 index 0000000000000000000000000000000000000000..40e986a4b9682b18312eb75db6077e737cf2e602 GIT binary patch literal 9919 zcmbW7Wl&r})9-P24{i&K+v2(ex3IXoOV9+D;EOD_XmI!78VK$#2_9U76C@;XdG7u6 zR^7L*d^k1LJ*WRuJ*UsFre+4JsiBCAMTv!gfPky4B&UUdfCznk6fjU;J%Ucv`mYU& zJy;!#fY6YL{nrxp)uy*r(o#o2@Ml3l2#r8M`19%tJwibEz>9!zVu64lmWhBs?w->L zk$CMuvQkx)LwJc!oc#7`p?fQ<%cCEm5##gYkhEAnA|L=pl;yxWzN=@ZekQt0cQ0X~ zp`w7yB2l~P^c~IEO53col>*%Cp3MaZ-%8u?9+z2{Ey>TbHJqpVLSOk8%u3Q7O2hVb z*qj{MMfPHd*)fpr@6oekG6KF!*`Ec?bk|%w4kQM{e9n#o?pB?@AQE7pAbpadCjeTq zN>JuaOei^)%8xTd_#Mw7aWzJuL94vHV)W9IY4UWLRO?k1W^f;3Onz=G%7eH-3rLgB&QaE zr%M`T`x{~n2l+rZ{0{0K@SxHD2}2x#EC6Z#O?T0j`rTNUX#;9TaZ(2=Ho=ar7VwGn z0%g@NSsNdH#izT%Yp7Yij*xUWSdUF{u5-PVAY9tew%bJ&P}~1EEzhzTcc!V;0)J;b z&708Ez&3$faoWPJw32BYA{e_I@%7v~tc*Xn&F!XxL~M)Vb4{e#J5CbNkkqgw->L$( zEMIgjDr$Rwd5x6F7|SUWo#(UlL4-)U@}QR7!;u<5$khGozEyjkvg4>+Jo2u*PmaYO zDRYM=REWVe=m47D7)4bWg7Nuy$M#>g8<~?aj*)JSWs<r7 zPY~#`_4JD>i01f_ecYNfnrzZi!69#VK*WoT(lXJNfd{CT6eRf#BPcChR`;({m!f&f zq5u}-W$u|?3E{UHy>`W$^O@obb={-|;zyQ`FEAl4L2ONB$7R}vl`O@y4A~rY`7<9K z`&+^a+Xecrjcad(Xj91-xA7FC?IbSchHOqgka%on%aKLWh+PH7ZC=2=D*8VwvX>84e5 z9afPS6^Be5SW&$HD|3n~3=DC}vv?22b%D6_iMjc7F~{rc+5K5b(!#8a^}H*t>&)ck zgb-clOo5$4|EUaijrUpkzMC7ZMt90kQzc1*U~xmPbuQ0!z#FLtRD6sk1xJ;$Kl3t& zv5?zV`mWq!Wc4?_nn|iGy29pl^oare^%`JDr@B(ym-%w93@{BfgX(JOFFilBf297P zi3qL@=)P3MFV1x5r@K4Qd)E7-H%9|$oG`xW8gr_#&LF|)#v=vzHf(Q_Da0;&g`6m1 zgPGymve;!F*uD$zt5A|giZ{U_n6-zog)x6_UWcrWVB{~uNJ>A{K4S_`cQAcWdlh8A z;g`T{6TfR&Y>GcDz=@h|`;2@vG*zNExv(6@OHJRhjf7?ha@|E8@pQnWm8?Y@7CuOF z!L5Xe3!t81y180p=FwdW9dp!?OD7v$;OQGfu|^U{G-{b{58`bIPEFF6KxtH z{|5^gF2(^Wn%Waz=oG#luL>`6*AL0!`##pSx( zs?P|i-JYG?q3IYEZj6N$wBMRHHSg&iX(~7faB1E7b!X?7%YP>rvV4|NgF33nH z^ZhaM!zo$!J4X?>^{xGJW+s36!5n3TZ&SwP5BfvPFAEF$;Ux(bHA>KF$}%@{Ctx!@ z9AFan5ns?GyadD}K4VY07ccFzmChR{^6R%ztyIAK$Xid+lKWSpF!T+7lz;|Z*Xg_T zm9}n_PXyRyR7ZJTOpSD#RS$__m;*2DrsD491tQ~oSfNPgR%fwaG>cBg&t1jNn>fT{ zmbN-)XeU;~IO$*+zmuoftG_<|daikFfEA_r@a1%n=H2swm0h&3xMZP5{O8JdZ=pHp zOI6YS>Hqv^ESx{-0wGA+C#W2M60QFRKDjGW4m0mj<$tH`S;xXRtMtlXGqSr}3Sn9_c;H`%~XEk0B0ULw)`i*s-bKiX3-dBDibyC%Z*=)u;D68;l*jx9cV9Ud!MKW^J;1f{H1V^CnPt_<}g3q zH~_Qi#PT12aO7D#d}<lm zc9o~qvp)S|({hHsOZnJSBRbDKf(i~095#E6L0kTc7bI6J{$rJ(X-;7|Avdn(-jypd zUC7gjPWG*xbT+mtXR1WA7v3Yq^v;6aH*#d9*g~!K9JP7b*6(9fA_=30U&&^JG)sK*@&ylAjLZ@;PUNEymz+ zW$%ym6e(%`B^-?!wL1$YxSOS1X;?q^3M#`T9n)L22Ul1#)XoOOjowG%;^h>$L5?PE z6jd2y`-DP9KlT7m6Q?{;ODhZ0g(~2){_Dvl*;vX@{Z_r)+3o0sKW7%t9z@wPeEyeT~U+tUr`(dv1i?5-%*~ZB(j&cUoI)oL0w<90YFXG>}T8mn9 zVz=5_=Lit~#(jguwyDvbMHcqkRW3qx8GH)_(={ruC`z;c{@iMMvxp45Q=2Ix0|eM zC=IyAh4jOz5hB$54)rlq7OmcJ_?!`?xCs=kNxshp=@nvT47a!l%i;U9nDnU2YCIGW@F_+V{)`#iHQ9y`A7|{|ggfYs|zY*gCRE+>H zxaC_|=I#SS*&~jmqfB>_lE3)ifx)}0fL6jyM`J{w<(a-o1Py13EQZGUib9N{2u&n^ zea7Kw&}#H9YYE@ep2b=cb-c{r3A}^-MEGD-pc! zt~Her9g7<V9w=-f> zzA2L9!V@jzRNvQhY$XQGqp4}b!M^3jN!mpm+qoZJh3>jsaXd|$R4=Imn=+%)kyQ3~ zH^J&LytfvVtaYZ0abQ@XX+PW#6zAx`_5hWGUecEh?xWZWqo3lQ6J&b8w1)9P?tY{)`BYzjA@&Sw*yC!Y>MhC|Qst0vxy& zF16}$qA}fY@l|ByEHJif<<*3LG>cAHBrQZ-YLKA=fRj~IMA?ohM3DwczNaj$reo?y z?_%K(QR;bYDjYD6g-b7Yf7Op0(RdDlo&SL=o?)HLWT{3;pi2WRTBpaOsU zqUgy`yhU+9yjhh{2v&fGByVPqu_StS4eY9ZAaqQ4vj!0H4#Xe(6ncSlMm%r4yPUG$ zj!5H9yj>eOX_u;WRl4Ir-7$EbATho<((?Kt142M5P?BFvUzd6n{^{KB7;520i>g`X z>*xw6fHiPsFJ)NvWs_u~(wK!iu7-6j!1PO6msDMu8ijijYpCf<5qX0ViTQ_wKPdLF zRD&^ks8&D($qTqJB6^FNdcR=M+);&uc=Si8YkyhlI)>GijV3`6kr|-74fSW!SP6;o zOXR-0dZ8Q|Ibd>wf|`+3wYm*+Y;;mBBpyV{s41>Z) zdF3#(PrSKy`TeqP^-wmkA9@!=tVHkM`X;K|QPf#w--NCMRvWzIuZOncZ60W)Q#Vh; zLeNA2n~ZreoBe!3S?~%R{L0L9Qdx|r2M?Ehs%c7K>*QMg&@C4Siw@(_Si8=9fZm-1 zEInRJ{YOT7^zwu?Yyy}u9ESq^)~Mv9kkp)Wr`>G2!^^74XmBp+35XV3Q82{7%%A?^nw6QNg9O$q@T$`;l9y1p@)Fh zy+;Ihs_oojPFBp-)rl>d?^Kwbt14v5mLh6Nf(b1?xe&RR{osSYZ|IW9HH6~girG|fm{T{x#SIj1`BNqX z;)Ck-AtCWqBDTa>zoH6>RnfoELz?MMQJ&*Weio1&r0|2=5%sOm{Gu{;1oT#3=)Vq- zrh!G3OT4th?ouVV{mi#Twrc|nSl!9z94Qg983gH7d_MGL>^USNt&gNI?SiHU&LY}+ zm_*Ge%ObE&YlX`rUs+S7O{mIjew;X<)fl_o=M;Use#@bev7ICvl4obeHK42&&1bl% zK~Ys@iZ+F5b(5t*+?I^yjTC_IMM^d&rii)WtzAS8W52bkhf;~E7T_u!R-@)1 zgK#Q%n(0R9>Y*F{G=kz}E3q zLX-+J6w8Vu={Nqpa&y)F=?m%R`!Mg}BU~v7*bJO;n9hEJAea(Ad2>f>`u=K0IqZ+^ z?rK3DLy)~*!+nF$v(75pwQDEx$ts}es!;1m@*$SQzB~+DDPR#&77%t&V&+uEF29Cn zTtAA{XP45P_pAF?Y~YZ*VE7StVLlPLb%NEJFmcsr<&J#HUfc3VW@p2$WyhBv{2R&y zFTAPEtjfrriwg5!bWHSUU35R%&4HnXDvD0{5~K3ycXQQYE-AlYYS%psqyGB&>0-I` z!HB6f{vygrdNqK}GgDhF5{s`XOHrSRJTi;d53CNJoc`#qy}gxcRUjEt5z(XrpizKo z5zUj)?zM6M;f%=cqaO76M^>w7s6_0Tm5RqK%n(y5aHo_g`z|9j0_V6RBW}l9A-Jf+ z+!mpy%HhU?Bs2Q0<<2gg{P6C>z&_P zMUs_-CXcPfG3L2$px>l|021`)cRvlJbC@$0xdZ9Gm(s4v z`Nk<~JhZJ?zP+Z*erP8dK8%7kD4)Nw4UPpX87H1@laHv*A>#)RP_>`x0PxrW{j;=8 zmuzGEDOR@g`V&vaR#bKNsSkq6u2|uSf58spMnaAsJaRyb(FR!a8Ex`2)`ltN#+?)s zN@yGT%E<_eaiY2D8C1|(gRui62!14rpIbkM8OR0IKT>4jEgr8*fU=2 zW*;+pc>I#aNS5@UO?$s1Fb}@2w(Ckg*v6<5?murtGrRG}Z;NV$KU69FVBG(B-5Z_( zy8lX9hDt)CVG(cF6-cr2kTeeb?Ugc!;stk5cbfH7fF=?~cWW-Fe{{rQBwqYEBW5L! z$?6*>A&}8HR-+#4xbnUg0cmO}-c6RVKAD5S+9 z#=sM^hLh0eTdGD;mM5L;pk(X&dA)2dUh9HcIR}5YfJPwS9=;sqvNEb5`L=i#B|kNG zFw-AqStLYP*4PeRuS%#n7n)G!cjJ2pg_T6n*a*h;sN_X}66&xIwLX+_I3y=J)^s(x zfdGHH{kIrO(+Z1Nm3L^vZ_KfzsqQ`^6)78)czgzhPG{PR`+wRM4O4chODB=D6zp)N zYgEx-7*h)~zeL~*Kt06WX~CMz#pIrgie8nwIee^B-CvO&o!a$Y* zJK7WJHHYa|hKFO^q0)2zT|Oh{5Qg;cb9O5ml#s91$VK*-3D3oH)+yoK_s1`Ik)=&J zEz599F$*NU`g~qbK71zck|@@qmi~=@gjPL7o03+=E5@gd1sgkc*6;TeRUB>DAH6~e z;=sPd&NSLg_^OwTf9S`*bXUf4eq&Qlh!Nh02GcND#pgz^7=P>3lFicJLR;)z@-PtvBm>%2oP>@^Z9Pk`Trz9KBxat&nVlLK1D5qx1IWQ+^S3m^uB zY~{Jp3i_O${z{?K`g%sg0@sv!`?cJG^I*D}&pd<3bp z+9$Gjc#I~D?yq#B)+b%cu_{N~!E1pc``&gUy{A7V(TH_`7`!5Y`+ksYvU&6Hg zNK9>tileCStTRkA;GK`Z7CW|OF~c6MN_X0WYx}fA{p<6wepnJT9DfF_5437=tF`pD zi+?D96s38NWi3(GkyR$c{f2jdX`DY6we-Z!$phFk4ou^)BZ>BRRQ3}mHE`=<3Jp}? z&+I0cCz5xVT)IlpY#N2=;w$VlC{zGi&F5a~?={Fg=zb z<#<9BIGDK-?qwMLo0iguNO7}rxVNP};#Yk6$l;M6mBtUcKY*hCTDU_fsn9(AQ6=JU z0OXlWu74;~Ve{nH;d)F+sR4@|6M%pqyc3#`d&k1%+L5~+_IcZBFh#hl!)PyhS;aah z4nmqol&sX6>|c%%-qKtqwi0qC-cFmC6z!En_LxROM3zHy=^2b#Hds1HxoeBbXQCZY zA%z)0^{Lq(F}BD&sW#`oM%oGu_3#%cJavYdx>;+0q1Z8T+3%x#thz7a2^3nZXaYEP&UMe!jCD}=5!f^ zw>nnT6dflJ_ur{3%A|z*uR4RubgN~BrhG3+knpBRduCr|mtkaBE3f1XeXcnc|ECUh zkT}_5+V0agB0dh3c|YQY77KIiT?od};7nK@9QWUssXUv~T_)qCP{xcBIsAVJ`YZ8?QPPC=p77N9_J=dg=sG=DMOpBFlw)s-3pb;ehMj z8o3Mth0q03;W0xLBc&{D&fIy_<@F)1cC{|H)bH4Fp5&%nk1ME?PHI6r24o}n+HeP0 z8+8bl!~ zLITczS7M#{VId~|!Loh!Y!>&3+_FSR8*N&u7@;9iT~vkMWft+C^pKX(uIi7vN8Xh@ zc7TwG(SU3$f0&AlclBG1WE?4Mt4BMyRhox=J?ltL?b8u2wtDvFr)a6|xVLu{E83my z9l8ajYIW2sIVX%`bk@s74AjlpE>j}P@3L4@X*jA?uTP76ErJAzZ6wU9e2 z!ZK@Wv|_3qf+88HJE%{WBI@vxFx}bhkZj#zQskvUYvMVoK#p0DjmGE#^u5vlA?d2! zRsH@S^F|0OjKVn;U6jIkGL0L>?NRix(Ro&L47*9@t;+uOT(Ut7KSjRPBq$rtJ4Nd> zy`w0*TF9isZE() z+&=G1RlUVm>RZ&qR6;-0QlJAp$LpsCIT z5~$~Q7m?Q&10Q1^m8sOjkY5}C-$e6`QOt)JNq zJ`bgi``3T7uFAGTvX%%tFUR<~YbM<_p{onCnY`in^bhs|e0TH2-9F)xaP_dU?`;qX z;cnlH9he!<8~mqPNEjxZ#u`BA)LwLUl^K&pnbVXj*^!x;Oet_(Sx~DbAvXrS!qf4M z*fQOBG`}bc9iYG&1nHZcx%Po@7BemNN%c9pxUz3TK8mt$3+x~NOwg!1c?%S?V3ztF zE}%rnf5{Tn&du(ZDU0`IVTMUIY9XdKkm@5GT=z@$EzU3rryh4{U7ol#cizAUZV2Oy zf(Xmn(VPK;tfL&;UVzw*npex3JF-b)$o4mbV<4Z$@jnak^etD37}|>Co#2rjajNcs zY02!b#_qH|vON1QEhKH0?+`SfB|r*Hpy9|EFxR52z@X7{{?sxQd2~3~MUkbko(2_h zb^&FwIr--aYJ6(Ywu#O#wJ|uS8>#-wdoI)q5@;({kR(&wx4!~IheBu|I(#gENvK1h z%>=GT1ZUvS@8$O{$16>OtkN~0}EB87O^3v%1Vn;IiAv3@TY@ey80N+s>EMhHv@5XnC+O%D$Tta zc*T7~u5X#pcH0N~8I|iq+|jWBlvdfYgl29tLK%@L=nSij1D4*a!4fcbSxi+>uQ=W$ zC19q!4krRvOpbBPqbl~It34qq$eN7e)w zr|y$c#0*o|?Qcy27TKBka`@FW8Hu`+BXqM<9xr+|$pI^51nvw{a|R*a_;%Y2-mO8Y zg{eeKv*^V2NmI@K=UzDPlvO_U%8>_FcZZ(eXU6o5_h^X$=Mcg##e(GvztbLCR}GG! z3Uyi)CLlD)A-S=R+ED$f4SKe z>lsjfSSG7hX?N8cwSM`#xiF_f_KtU#Xwu??EylqiZwlmHx|+NUP5cPh@LDRrmSX=N z9G zflvuEs-&<;gZNbb23gE_;73M2mSJO5wb z|8Gb7{~7#$EB0SAIVFVsiD=6n|Mh^(z>k7P813u*7HNl2*;-*^=<`bgm&ahGxEhC0mL~hm8DS_5j4m^dvz4`J_ajWDtA*@kI|gP00@37vdVyX zr6jXUf4;9=BQK_B&DS~x#|Di5B<^HDq=9tE{tgh<`;UAiapP+d*ynKh7kosegDyM` zYuR7{*cny0zx(EL{UW~7H?9pRBiqR%%i5u&?LzHj z5clKnzvpP?u5Ec^+`VNvUh9rv@c&qg!C-gMVcijV{?g$F;s9HM|8z+2wH+s4w{R?OPd_O(Ia=j8`+@d|PAiR$nPiV5yoOwztVP)W0NNrI4FCWD literal 0 HcmV?d00001 diff --git a/libs/adafruit-circuit-playground-bluefruit/board.svg b/libs/adafruit-circuit-playground-bluefruit/board.svg index 16e46169..7dc70c62 100644 --- a/libs/adafruit-circuit-playground-bluefruit/board.svg +++ b/libs/adafruit-circuit-playground-bluefruit/board.svg @@ -1 +1,181 @@ -AB \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + diff --git a/libs/adafruit-grand-central-m4-express/board.svg b/libs/adafruit-grand-central-m4-express/board.svg index 3d387568..a27d2989 100644 --- a/libs/adafruit-grand-central-m4-express/board.svg +++ b/libs/adafruit-grand-central-m4-express/board.svg @@ -1,9439 +1,3134 @@ - -image/svg+xml - - - + + + + - - + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - + + - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - + + - - + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - - - - - - + + + + + + + - - + + - - + + - - + + - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - - - + + + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + - - - - + + + + - - + + - - + + - - + + - - + + @@ -9446,174 +3141,72 @@ - - - - - - - + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - + + + - - + + @@ -9626,71 +3219,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -9700,29 +3248,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -9732,53 +3267,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -9788,29 +3292,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -9820,53 +3311,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -9876,29 +3336,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -9908,53 +3355,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -9964,29 +3380,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -9996,53 +3399,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -10052,29 +3424,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -10084,53 +3443,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -10140,29 +3468,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -10172,2434 +3487,612 @@ - - - - + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/libs/adafruit-itsybitsy-nrf52840-express/board.svg b/libs/adafruit-itsybitsy-nrf52840-express/board.svg index bb767b65..e564b9dd 100644 --- a/libs/adafruit-itsybitsy-nrf52840-express/board.svg +++ b/libs/adafruit-itsybitsy-nrf52840-express/board.svg @@ -1 +1,897 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/adafruit-neotrellis-m4-express/board.svg b/libs/adafruit-neotrellis-m4-express/board.svg index eeb2475f..b05b2b5d 100644 --- a/libs/adafruit-neotrellis-m4-express/board.svg +++ b/libs/adafruit-neotrellis-m4-express/board.svg @@ -1,68 +1,5 @@ - - - - - - - - - - image/svg+xml - - - - - - - + + + diff --git a/libs/adafruit-trinket-m0/board.svg b/libs/adafruit-trinket-m0/board.svg index e3ff83a6..c37f7cc1 100644 --- a/libs/adafruit-trinket-m0/board.svg +++ b/libs/adafruit-trinket-m0/board.svg @@ -291,8 +291,6 @@ - - diff --git a/libs/adafruit-trinket-m0/boardhd.svg b/libs/adafruit-trinket-m0/boardhd.svg index 34be1f7a..84272068 100644 --- a/libs/adafruit-trinket-m0/boardhd.svg +++ b/libs/adafruit-trinket-m0/boardhd.svg @@ -1235,24 +1235,6 @@ y="-27.568602" id="connector84pin" transform="rotate(90)" /> - - diff --git a/libs/atisa-menorah/BreadboardViewGraphic_Template.svg b/libs/atisa-menorah/BreadboardViewGraphic_Template.svg new file mode 100644 index 00000000..9fa80084 --- /dev/null +++ b/libs/atisa-menorah/BreadboardViewGraphic_Template.svg @@ -0,0 +1,297 @@ + + + + + + + + + + 0.1 inch + + + + 0.03 inch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atisa + Menorah + + diff --git a/libs/atisa-menorah/README.md b/libs/atisa-menorah/README.md new file mode 100644 index 00000000..2d4da3c8 --- /dev/null +++ b/libs/atisa-menorah/README.md @@ -0,0 +1,18 @@ +# Atisa Menorah + +Support for the Atisa Menorah board in Microsoft MakeCode. + +## Board Details + +- **Microcontroller**: [Your microcontroller details here] +- **Features**: [List key features of the board] +- **Pins**: [Describe the pinout if needed] + +## Getting Started + +1. Add this package to your project +2. Start coding! + +## Documentation + +For more information, visit [your documentation link]. diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json new file mode 100644 index 00000000..1abced74 --- /dev/null +++ b/libs/atisa-menorah/board.json @@ -0,0 +1,29 @@ +{ + "driveDisplayName": "", + "visual": { + "image": "pkg://board.svg", + "useCrocClips": false, + "width": 63.98745346069336, + "height": 85.5889892578125, + "pinDist": 15, + "pinBlocks": [], + "leds": [], + "touchPads": [], + "buttons": [] + }, + "gpioPinMap": {}, + "groundPins": [], + "threeVoltPins": [], + "fiveVoltPins": [], + "i2cPins": { + "SDA": "SDA", + "SCL": "SCL" + }, + "onboardComponents": [], + "marginWhenBreadboarding": [ + 0, + 0, + 80, + 0 + ] + } \ No newline at end of file diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg new file mode 100644 index 00000000..150e12fa --- /dev/null +++ b/libs/atisa-menorah/board.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + 0.1 inch + + + + + + 0.03 inch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atisa + + + Menorah + + + diff --git a/libs/atisa-menorah/config.ts b/libs/atisa-menorah/config.ts new file mode 100644 index 00000000..2631a6ee --- /dev/null +++ b/libs/atisa-menorah/config.ts @@ -0,0 +1,3 @@ +namespace config { + // additional pins to look for: SPI, I2C, Flash +} \ No newline at end of file diff --git a/libs/atisa-menorah/device.d.ts b/libs/atisa-menorah/device.d.ts new file mode 100644 index 00000000..de6ded79 --- /dev/null +++ b/libs/atisa-menorah/device.d.ts @@ -0,0 +1,112 @@ +declare namespace pins { + //% fixedInstance shim=pxt::getPin(PIN_LED) + const LED: PwmOnlyPin; + + //% fixedInstance shim=pxt::getPin(PIN_D0) + const D0: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_D1) + const D1: AnalogOutPin; + //% fixedInstance shim=pxt::getPin(PIN_D2) + const D2: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_D3) + const D3: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_D4) + const D4: PwmPin; + + //% fixedInstance shim=pxt::getPin(PIN_A0) + const A0: AnalogOutPin; + //% fixedInstance shim=pxt::getPin(PIN_A1) + const A1: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_A2) + const A2: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_A3) + const A3: PwmPin; + //% fixedInstance shim=pxt::getPin(PIN_A4) + const A4: PwmPin; + + //% fixedInstance shim=pxt::getPin(PIN_D13) + const D13: DigitalInOutPin; + + //% fixedInstance shim=pxt::getPin(PIN_D0) + const SDA: DigitalInOutPin; + //% fixedInstance shim=pxt::getPin(PIN_D2) + const SCL: DigitalInOutPin; + + //% fixedInstance shim=pxt::getPin(PIN_D3) + const SCK: DigitalInOutPin; + //% fixedInstance shim=pxt::getPin(PIN_D2) + const MISO: DigitalInOutPin; + //% fixedInstance shim=pxt::getPin(PIN_D4) + const MOSI: DigitalInOutPin; + + //% fixedInstance shim=pxt::getPin(PIN_D3) + const RX: DigitalInOutPin; + //% fixedInstance shim=pxt::getPin(PIN_D4) + const TX: DigitalInOutPin; +} + +declare namespace input { + /** + * Capacitive pin D1 + */ + //% block="touch D1" fixedInstance shim=pxt::getTouchButton(PIN_D1) + const touchD1: TouchButton; + + /** + * Capacitive pin D3 + */ + //% block="touch D3" fixedInstance shim=pxt::getTouchButton(PIN_D3) + const touchD3: TouchButton; + + /** + * Capacitive pin D4 + */ + //% block="touch D4" fixedInstance shim=pxt::getTouchButton(PIN_D4) + const touchD4: TouchButton; + + /** + * Button connecting D0 to GND. + */ + //% block="button D0" fixedInstance + //% shim=pxt::getButtonByPin(PIN_D0,BUTTON_ACTIVE_LOW_PULL_UP) + //% parts="buttons" + const buttonD0: Button; + + + /** + * Button connecting D1 to GND. + */ + //% block="button D1" fixedInstance + //% shim=pxt::getButtonByPin(PIN_D1,BUTTON_ACTIVE_LOW_PULL_UP) + //% parts="buttons" + const buttonD1: Button; + + + /** + * Button connecting D2 to GND. + */ + //% block="button D2" fixedInstance + //% shim=pxt::getButtonByPin(PIN_D2,BUTTON_ACTIVE_LOW_PULL_UP) + //% parts="buttons" + const buttonD2: Button; + + + /** + * Button connecting D3 to GND. + */ + //% block="button D3" fixedInstance + //% shim=pxt::getButtonByPin(PIN_D3,BUTTON_ACTIVE_LOW_PULL_UP) + //% parts="buttons" + const buttonD3: Button; + + + /** + * Button connecting D4 to GND. + */ + //% block="button D4" fixedInstance + //% shim=pxt::getButtonByPin(PIN_D4,BUTTON_ACTIVE_LOW_PULL_UP) + //% parts="buttons" + const buttonD4: Button; +} + + diff --git a/libs/atisa-menorah/pxt.json b/libs/atisa-menorah/pxt.json new file mode 100644 index 00000000..c7862d1a --- /dev/null +++ b/libs/atisa-menorah/pxt.json @@ -0,0 +1,40 @@ +{ + "name": "atisa-menorah", + "description": "Support for ATISA Menorah", + "files": [ + "README.md", + "device.d.ts", + "config.ts", + "board.json", + "board.svg" + ], + "core": true, + "dependencies": { + "core---samd": "file:../core---samd", + "buttons": "file:../buttons", + "light": "file:../light", + "mixer---samd": "file:../mixer---samd", + "touch": "file:../touch", + "pixel": "file:../pixel" + }, + "public": true, + "compileServiceVariant": "samd21", + "firmwareUrl": "https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/uf2-bootloader-details#updating-the-bootloader", + "features": [ + "uf2", + "i2c", + "pixel", + "pinled", + "pind0", + "pind1", + "pina0", + "pina1", + "buttond0", + "buttond1", + "touchd0", + "touchd1", + "light", + "jacdac", + "music" + ] +} \ No newline at end of file diff --git a/libs/brain-nrf52840/board.svg b/libs/brain-nrf52840/board.svg index f41ea9c1..e816990a 100644 --- a/libs/brain-nrf52840/board.svg +++ b/libs/brain-nrf52840/board.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + + + + + diff --git a/libs/espressif-esp32-devkit-c/board.svg b/libs/espressif-esp32-devkit-c/board.svg index 64d4383d..62494d95 100644 --- a/libs/espressif-esp32-devkit-c/board.svg +++ b/libs/espressif-esp32-devkit-c/board.svg @@ -1 +1,64 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/machachi/board.svg b/libs/machachi/board.svg index f41ea9c1..e816990a 100644 --- a/libs/machachi/board.svg +++ b/libs/machachi/board.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + + + + + diff --git a/libs/xinabox-cc03/board.svg b/libs/xinabox-cc03/board.svg index baa86232..7effd208 100644 --- a/libs/xinabox-cc03/board.svg +++ b/libs/xinabox-cc03/board.svg @@ -1,7 +1,7 @@ - - + + @@ -9,7 +9,6 @@ - @@ -601,13 +600,13 @@ - + - - + + @@ -1108,6 +1107,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7259,107 +7356,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - diff --git a/libs/xinabox-cs11/board.svg b/libs/xinabox-cs11/board.svg index 5b026651..2649532b 100644 --- a/libs/xinabox-cs11/board.svg +++ b/libs/xinabox-cs11/board.svg @@ -1,7 +1,7 @@ - - + + @@ -603,8 +603,8 @@ - - + + @@ -646,7 +646,7 @@ - + @@ -1090,13 +1090,11 @@ - - @@ -1109,6 +1107,8 @@ + + @@ -7060,6 +7060,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7208,107 +7307,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/pxtarget.json b/pxtarget.json index 683fa6ce..f2a4ac6f 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -7,6 +7,7 @@ "description": "A Blocks / JavaScript code editor for MakeCode Maker Boards", "corepkg": "core", "bundleddirs": [ + "libs/atisa-menorah", "libs/base", "libs/base---light", "libs/core", From ef9a4b460058d93d08de10341442d10250c5ca0c Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Fri, 11 Jul 2025 11:12:50 -0700 Subject: [PATCH 02/19] tried to add led manually via board.json --- .../BreadboardViewGraphic_Template.svg | 10 +- libs/atisa-menorah/board.json | 54 +- libs/atisa-menorah/board.svg | 2 +- libs/atisa-menorah/config.ts | 35 +- libs/atisa-menorah/fritzing-board_view.svg | 4928 +++++++++++++++++ 5 files changed, 5011 insertions(+), 18 deletions(-) create mode 100644 libs/atisa-menorah/fritzing-board_view.svg diff --git a/libs/atisa-menorah/BreadboardViewGraphic_Template.svg b/libs/atisa-menorah/BreadboardViewGraphic_Template.svg index 9fa80084..f84d0ec2 100644 --- a/libs/atisa-menorah/BreadboardViewGraphic_Template.svg +++ b/libs/atisa-menorah/BreadboardViewGraphic_Template.svg @@ -10,7 +10,6 @@ viewBox="0 0 63.987455 85.588988" xml:space="preserve" id="svg838" - xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> @@ -19,14 +18,7 @@ transform="translate(-252.75507,-354.00001)"> - + diff --git a/libs/atisa-menorah/config.ts b/libs/atisa-menorah/config.ts index 2631a6ee..e47f2660 100644 --- a/libs/atisa-menorah/config.ts +++ b/libs/atisa-menorah/config.ts @@ -1,3 +1,34 @@ + namespace config { - // additional pins to look for: SPI, I2C, Flash -} \ No newline at end of file + export const PIN_ONBOARD_DOTSTAR_DATA = DAL.PA00; + export const PIN_ONBOARD_DOTSTAR_CLOCK = DAL.PA01; + export const NUM_ONBOARD_DOTSTARS = 1; + + export const PIN_D0 = DAL.PA08; + export const PIN_D1 = DAL.PA02; + export const PIN_D2 = DAL.PA09; + export const PIN_D3 = DAL.PA07; + export const PIN_D4 = DAL.PA06; + export const PIN_D13 = DAL.PA10; + + export const PIN_A0 = PIN_D1; + export const PIN_A1 = PIN_D2; + export const PIN_A3 = PIN_D3; + export const PIN_A2 = PIN_D4; + export const PIN_A4 = PIN_D0; + + export const PIN_LED = DAL.PA10; + + export const PIN_SDA = PIN_D0; + export const PIN_SCL = PIN_D2; + + export const PIN_SCK = PIN_D3; + export const PIN_MISO = PIN_D2; + export const PIN_MOSI = PIN_D4; + + export const PIN_RX = PIN_D3; + export const PIN_TX = PIN_D4; + + // not supported + export const PIN_JACK_TX = PIN_TX; +} diff --git a/libs/atisa-menorah/fritzing-board_view.svg b/libs/atisa-menorah/fritzing-board_view.svg new file mode 100644 index 00000000..e80ce547 --- /dev/null +++ b/libs/atisa-menorah/fritzing-board_view.svg @@ -0,0 +1,4928 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 1 + + + 5 + + + 5 + + + 10 + + + 10 + + + 15 + + + 15 + + + 20 + + + 20 + + + 25 + + + 25 + + + 30 + + + 30 + + + 35 + + + 35 + + + 40 + + + 40 + + + 45 + + + 45 + + + 50 + + + 50 + + + 55 + + + 55 + + + 60 + + + 60 + + + A + + + A + + + B + + + B + + + C + + + C + + + D + + + D + + + E + + + E + + + F + + + F + + + G + + + G + + + H + + + H + + + I + + + I + + + J + + + J + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +5V + + + + + + + + + + + + + + + + + + + + + + + + + GND + + + + + + + + + + + + + + + + + + + + + + + + + GND + + + + + + + + + + + + + + + + + + + + + + + + + +5V + + + + + + + + + + + + + + + + + + + + + + + + + Din + + + + + + + + + + + + + + + + + + + + + + + + + Dout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +5V + + + + + + + + + + + + + + + + + + + + + + + + + GND + + + + + + + + + + + + + + + + + + + + + + + + + GND + + + + + + + + + + + + + + + + + + + + + + + + + +5V + + + + + + + + + + + + + + + + + + + + + + + + + Din + + + + + + + + + + + + + + + + + + + + + + + + + Dout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From fb5159fe62f562b23ba77761131bb6a1704cc6fd Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Fri, 11 Jul 2025 12:14:31 -0700 Subject: [PATCH 03/19] reset board in menorah to trinket+menorah --- libs/adafruit-trinket-m0/board.svg | 2 + libs/adafruit-trinket-m0/boardhd.svg | 18 + libs/atisa-menorah/board.json | 219 ++-- libs/atisa-menorah/board.svg | 744 +++++++++++-- libs/atisa-menorah/boardhd.svg | 1474 ++++++++++++++++++++++++++ 5 files changed, 2321 insertions(+), 136 deletions(-) create mode 100644 libs/atisa-menorah/boardhd.svg diff --git a/libs/adafruit-trinket-m0/board.svg b/libs/adafruit-trinket-m0/board.svg index c37f7cc1..e3ff83a6 100644 --- a/libs/adafruit-trinket-m0/board.svg +++ b/libs/adafruit-trinket-m0/board.svg @@ -291,6 +291,8 @@ + + diff --git a/libs/adafruit-trinket-m0/boardhd.svg b/libs/adafruit-trinket-m0/boardhd.svg index 84272068..a696669a 100644 --- a/libs/adafruit-trinket-m0/boardhd.svg +++ b/libs/adafruit-trinket-m0/boardhd.svg @@ -1235,6 +1235,24 @@ y="-27.568602" id="connector84pin" transform="rotate(90)" /> + + diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 98d9e75b..eb65f2e4 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -1,71 +1,150 @@ { - "driveDisplayName": "", - "visual": { - "image": "pkg://board.svg", - "useCrocClips": false, - "width": 63.98745346069336, - "height": 85.5889892578125, - "pinDist": 15, - "pinBlocks": [], - "leds": [ - { - "x": 30, - "y": 70, - "w": 4, - "h": 4, - "color": "#ff0000", - "label": "LED" - }, - { - "x": 30, - "y": 60, - "w": 5, - "h": 5, - "color": "neopixel", - "label": "NEOPIXEL" - } - ], - "touchPads": [], - "buttons": [] - }, - "gpioPinMap": { - "LED": "D13", - "NEOPIXEL": "D4", - "D0": "D0", - "D1": "D1", - "D2": "D2", - "D3": "D3", - "D4": "D4", - "A0": "A0", - "A1": "A1", - "A2": "A2", - "A3": "A3", - "A4": "A4", - "SCL": "SCL", - "SDA": "SDA", - "MOSI": "MOSI", - "MISO": "MISO", - "SCK": "SCK", - "TX": "TX", - "RX": "RX" - }, - "groundPins": ["GND"], - "threeVoltPins": ["3V3"], - "fiveVoltPins": ["5V"], - "i2cPins": { - "SDA": "SDA", - "SCL": "SCL" - }, - "spiPins": { - "MOSI": "MOSI", - "MISO": "MISO", - "SCK": "SCK" - }, - "onboardComponents": ["pixel"], - "marginWhenBreadboarding": [ - 0, - 0, - 80, - 0 - ] - } \ No newline at end of file + "driveDisplayName": "", + "visual": { + "image": "pkg://board.svg", + "useCrocClips": false, + "width": 409.62432861328125, + "height": 485.56903076171875, + "pinDist": 15, + "pinBlocks": [ + { + "x": 227.7543777712405, + "y": 369.6968222703879, + "labels": [ + "VBAT" + ] + }, + { + "x": 208.02269350583958, + "y": 369.6968222703879, + "labels": [ + "GND" + ] + }, + { + "x": 188.272298156588, + "y": 369.6968222703879, + "labels": [ + "A4_D4_TX_MOSI" + ] + }, + { + "x": 168.53436923850828, + "y": 369.6968222703879, + "labels": [ + "A3_D3_RX_SCK" + ] + }, + { + "x": 148.80268497310735, + "y": 468.1922676403129, + "labels": [ + "3V3" + ] + }, + { + "x": 168.53436923850828, + "y": 468.1922676403129, + "labels": [ + "A1_D2_SCL_MISO" + ] + }, + { + "x": 188.272298156588, + "y": 468.1922676403129, + "labels": [ + "A0_D1" + ] + }, + { + "x": 208.02269350583958, + "y": 468.1922676403129, + "labels": [ + "A2_D0_SDA" + ] + }, + { + "x": 114.9234312624489, + "y": 412.6453022009505, + "labels": [ + "RESET" + ] + } + ], + "leds": [ + { + "x": 282.4396476240902, + "y": 466.13103997939635, + "w": 6.264919207243066, + "h": 6.264880191660064, + "color": "#ff0000", + "label": "LED" + }, + { + "x": 189.12175391438566, + "y": 405.53091929957327, + "w": 11.136937754336072, + "h": 10.056290621329891, + "color": "neopixel", + "label": "NEOPIXEL" + } + ], + "touchPads": [], + "buttons": [] + }, + "gpioPinMap": { + "VBAT": "VBAT", + "GND": "GND", + "A4_D4_TX_MOSI": "A4_D4_TX_MOSI", + "A4": "A4_D4_TX_MOSI", + "D4": "A4_D4_TX_MOSI", + "TX": "A4_D4_TX_MOSI", + "MOSI": "A4_D4_TX_MOSI", + "A3_D3_RX_SCK": "A3_D3_RX_SCK", + "A3": "A3_D3_RX_SCK", + "D3": "A3_D3_RX_SCK", + "RX": "A3_D3_RX_SCK", + "SCK": "A3_D3_RX_SCK", + "3V3": "3V3", + "A1_D2_SCL_MISO": "A1_D2_SCL_MISO", + "A1": "A1_D2_SCL_MISO", + "D2": "A1_D2_SCL_MISO", + "SCL": "A1_D2_SCL_MISO", + "MISO": "A1_D2_SCL_MISO", + "A0_D1": "A0_D1", + "A0": "A0_D1", + "D1": "A0_D1", + "A2_D0_SDA": "A2_D0_SDA", + "A2": "A2_D0_SDA", + "D0": "A2_D0_SDA", + "SDA": "A2_D0_SDA", + "LED": "LED", + "RESET": "RESET", + "NEOPIXEL": "NEOPIXEL" + }, + "groundPins": [ + "GND" + ], + "threeVoltPins": [ + "3V3" + ], + "fiveVoltPins": [], + "i2cPins": { + "SDA": "SDA", + "SCL": "SCL" + }, + "onboardComponents": [ + "pixel" + ], + "marginWhenBreadboarding": [ + 0, + 0, + 80, + 0 + ], + "spiPins": { + "MOSI": "MOSI", + "MISO": "MISO", + "SCK": "SCK" + } +} \ No newline at end of file diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index c1871725..4dd6f89e 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -1,70 +1,682 @@ - - - - - - - - - - - - - - - - - - - - 0.1 inch - - - - - - 0.03 inch - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Atisa - - - Menorah - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg new file mode 100644 index 00000000..2bb84c2b --- /dev/null +++ b/libs/atisa-menorah/boardhd.svg @@ -0,0 +1,1474 @@ + + + + + + +element:BATpackage:JSTPH2element:CN1package:4UCONN_20329_V2element:IC3package:QFN32_5MMelement:JP3package:1X05_ROUND_76element:JP4package:1X05_ROUND_76element:Lpackage:CHIPLED_0603_NOOUTLINEpolygonelement:PWRpackage:CHIPLED_0603_NOOUTLINEpolygonelement:Q2package:BTN_KMR2_4.6X2.8element:SWCpackage:B1,27element:SWDpackage:B1,27element:U$1package:TRINKET_M0_BOTTOMelement:U$6package:FIDUCIAL_1MMelement:U$8package:MOUNTINGHOLE_2.0_PLATEDelement:U$9package:MOUNTINGHOLE_2.0_PLATEDelement:U$12package:PCBFEAT-REV-040element:U$20package:TRINKET_M0_TOPimage/svg+xml From 8cc1e43cc9b7da37a314bceb2c9f1ead5b0617a5 Mon Sep 17 00:00:00 2001 From: angelinamkr <82286088+angelinamkr@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:44:40 -0700 Subject: [PATCH 04/19] Atisa 143 trinket default board (#5) * setting a default board, removing unnecessary galleries, adding a new gallery, and changing some theme/images * removed excess files * sets trinket m0 to default board (MAIN FEATURE) --- libs/blocksprj/pxt.json | 2 +- pxtarget.json | 7 ++++++- static/static | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) create mode 120000 static/static diff --git a/libs/blocksprj/pxt.json b/libs/blocksprj/pxt.json index b4174eb5..2d6541ef 100644 --- a/libs/blocksprj/pxt.json +++ b/libs/blocksprj/pxt.json @@ -1,7 +1,7 @@ { "name": "{0}", "dependencies": { - "adafruit-metro-m0-express": "file:../adafruit-metro-m0-express" + "adafruit-trinket-m0": "file:../adafruit-trinket-m0" }, "description": "", "files": [ diff --git a/pxtarget.json b/pxtarget.json index f2a4ac6f..eabed4b3 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -130,6 +130,11 @@ "parts": true, "partsAspectRatio": 0.69, "dynamicBoardDefinition": true, + "defaultBoard": { + "name": "Adafruit Trinket M0", + "url": "libs/adafruit-trinket-m0", + "variant": "samd21" + }, "messageSimulators": { "jacdac": { "url": "https://microsoft.github.io/jacdac-docs/tools/makecode-sim?webusb=0&parentOrigin=$PARENT_ORIGIN$", @@ -451,7 +456,7 @@ "homeScreenHeroGallery": "/hero-banner", "debugger": true, "print": true, - "chooseBoardOnNewProject": true, + "chooseBoardOnNewProject": false, "lightToc": true, "instructions": true, "docMenu": [ diff --git a/static/static b/static/static new file mode 120000 index 00000000..5de43723 --- /dev/null +++ b/static/static @@ -0,0 +1 @@ +/root/repos/maker-fork/pxt-atisa/docs/static \ No newline at end of file From bb77b4f02df1045c6e071255f24ae30fb73101ef Mon Sep 17 00:00:00 2001 From: angelinamkr <82286088+angelinamkr@users.noreply.github.com> Date: Wed, 2 Jul 2025 17:50:43 -0700 Subject: [PATCH 05/19] Atisa 135 welcome page (#9) * youtube video attached, all features for my projects and tutorials added/working * adding 'replace' comments to note what to change when we have content. This is for youtube link, galleries, and tutorials * updated starter code example --- docs/projects.md | 150 +++++---------------------- docs/projects/SUMMARY.md | 120 +++++++-------------- docs/projects/christmas.md | 73 +++++++++++++ docs/projects/christmas/ex1.md | 9 ++ docs/projects/christmas/ex2.md | 9 ++ docs/projects/christmas/ex3.md | 9 ++ docs/projects/christmas/ex4.md | 9 ++ docs/projects/christmas/ex5.md | 9 ++ docs/projects/christmas/ex6.md | 9 ++ docs/projects/christmas/ex7.md | 9 ++ docs/projects/hanukkah.md | 73 +++++++++++++ docs/projects/hanukkah/ex1.md | 9 ++ docs/projects/hanukkah/ex2.md | 9 ++ docs/projects/hanukkah/ex3.md | 9 ++ docs/projects/hanukkah/ex4.md | 9 ++ docs/projects/hanukkah/ex5.md | 9 ++ docs/projects/hanukkah/ex6.md | 9 ++ docs/projects/hanukkah/ex7.md | 9 ++ docs/projects/kwanzaa.md | 73 +++++++++++++ docs/projects/kwanzaa/ex1.md | 9 ++ docs/projects/kwanzaa/ex2.md | 9 ++ docs/projects/kwanzaa/ex3.md | 9 ++ docs/projects/kwanzaa/ex4.md | 9 ++ docs/projects/kwanzaa/ex5.md | 9 ++ docs/projects/kwanzaa/ex6.md | 9 ++ docs/projects/kwanzaa/ex7.md | 9 ++ docs/projects/my-gallery.md | 43 ++++++++ docs/projects/my-gallery/blinking.md | 29 ++++++ docs/projects/my-gallery/servo.md | 48 +++++++++ docs/projects/my-gallery/temp.md | 18 ++++ docs/projects/parole.md | 73 +++++++++++++ docs/projects/parole/ex1.md | 9 ++ docs/projects/parole/ex2.md | 9 ++ docs/projects/parole/ex3.md | 9 ++ docs/projects/parole/ex4.md | 9 ++ docs/projects/parole/ex5.md | 9 ++ docs/projects/parole/ex6.md | 9 ++ docs/projects/parole/ex7.md | 9 ++ targetconfig.json | 27 ++--- 39 files changed, 750 insertions(+), 229 deletions(-) create mode 100644 docs/projects/christmas.md create mode 100644 docs/projects/christmas/ex1.md create mode 100644 docs/projects/christmas/ex2.md create mode 100644 docs/projects/christmas/ex3.md create mode 100644 docs/projects/christmas/ex4.md create mode 100644 docs/projects/christmas/ex5.md create mode 100644 docs/projects/christmas/ex6.md create mode 100644 docs/projects/christmas/ex7.md create mode 100644 docs/projects/hanukkah.md create mode 100644 docs/projects/hanukkah/ex1.md create mode 100644 docs/projects/hanukkah/ex2.md create mode 100644 docs/projects/hanukkah/ex3.md create mode 100644 docs/projects/hanukkah/ex4.md create mode 100644 docs/projects/hanukkah/ex5.md create mode 100644 docs/projects/hanukkah/ex6.md create mode 100644 docs/projects/hanukkah/ex7.md create mode 100644 docs/projects/kwanzaa.md create mode 100644 docs/projects/kwanzaa/ex1.md create mode 100644 docs/projects/kwanzaa/ex2.md create mode 100644 docs/projects/kwanzaa/ex3.md create mode 100644 docs/projects/kwanzaa/ex4.md create mode 100644 docs/projects/kwanzaa/ex5.md create mode 100644 docs/projects/kwanzaa/ex6.md create mode 100644 docs/projects/kwanzaa/ex7.md create mode 100644 docs/projects/my-gallery.md create mode 100644 docs/projects/my-gallery/blinking.md create mode 100644 docs/projects/my-gallery/servo.md create mode 100644 docs/projects/my-gallery/temp.md create mode 100644 docs/projects/parole.md create mode 100644 docs/projects/parole/ex1.md create mode 100644 docs/projects/parole/ex2.md create mode 100644 docs/projects/parole/ex3.md create mode 100644 docs/projects/parole/ex4.md create mode 100644 docs/projects/parole/ex5.md create mode 100644 docs/projects/parole/ex6.md create mode 100644 docs/projects/parole/ex7.md diff --git a/docs/projects.md b/docs/projects.md index a4a765b0..801ca101 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -7,41 +7,36 @@ ```codecard [ { - "name": "Jacdac", - "url": "/boards/jacdac", - "imageUrl": "/static/libs/jacdac-iot-s2.jpg" + "name": "Parole", + "url": "/projects/parole", + "imageUrl": "/static/projects/digital-io/blinky/gallery.png" }, { - "name": "Adafruit", - "url": "/boards/adafruit", - "imageUrl": "/static/libs/adafruit-metro-m0-express.jpg" - }, - { - "name": "Arduino", - "url": "/boards/arduino", - "imageUrl": "/static/libs/arduino-mkr1000.jpg" + "name": "Hanukkah", + "url": "/projects/hanukkah", + "imageUrl": "/static/projects/digital-io/blinky/gallery.png" }, { - "name": "SparkFun", - "url": "/boards/sparkfun", - "imageUrl": "/static/libs/sparkfun-redboard-turbo.jpg" + "name": "Christmas", + "url": "/projects/christmas", + "imageUrl": "/static/projects/digital-io/blinky/gallery.png" }, { - "name": "XinaBox", - "url": "/boards/xinabox", - "imageUrl": "/static/libs/xinabox-cc03.jpg" + "name": "Kwanzaa", + "url": "/projects/kwanzaa", + "imageUrl": "/static/projects/digital-io/blinky/gallery.png" }, { - "name": "Misc", - "url": "/boards/misc", - "imageUrl": "/static/libs/robotics-masters-robohatmm1-m4.jpg" + "name": "My Gallery", + "url": "/projects/my-gallery", + "imageUrl": "/static/projects/digital-io/blinky/gallery.png", + "largeImageUrl": "/static/projects/analog-io/blink-to-light/gallery.gif", + "videoUrl": "/static/projects/analog-io/blink-to-light/gallery.mp4" }, { - "name": "Digital IO", - "url": "/projects/digital-io", - "imageUrl": "/static/projects/digital-io/blinky/gallery.png", - "largeImageUrl": "/static/projects/digital-io/blinky/gallery.gif", - "videoUrl": "/static/projects/digital-io/blinky/gallery.mp4" + "name": "Adafruit", + "url": "/boards/adafruit", + "imageUrl": "/static/libs/adafruit-metro-m0-express.jpg" }, { "name": "Analog IO", @@ -49,109 +44,16 @@ "imageUrl": "/static/projects/analog-io/blink-to-light/gallery.png", "largeImageUrl": "/static/projects/analog-io/blink-to-light/gallery.gif", "videoUrl": "/static/projects/analog-io/blink-to-light/gallery.mp4" - }, - { - "name": "Pixel", - "url": "/projects/pixel", - "imageUrl": "/static/projects/pixel/blinky/gallery.png", - "largeImageUrl": "/static/projects/pixel/blinky/gallery.gif", - "videoUrl": "/static/projects/pixel/blinky/gallery.mp4" - }, - { - "name": "Light", - "url": "/projects/light", - "imageUrl": "/static/projects/light/rainbow/gallery.png", - "largeImageUrl": "/static/projects/light/rainbow/gallery.gif", - "videoUrl": "/static/projects/light/rainbow/gallery.mp4" - }, - { - "name": "Music", - "url": "/projects/music", - "imageUrl": "/static/projects/music/play-sound/gallery.png", - "largeImageUrl": "/static/projects/music/play-sound/gallery.gif", - "videoUrl": "/static/projects/music/play-sound/gallery.mp4" - }, - { - "name": "Servos", - "url": "/projects/servos", - "imageUrl": "/static/projects/servos/sweep/gallery.png", - "largeImageUrl": "/static/projects/servos/sweep/gallery.gif", - "videoUrl": "/static/projects/servos/sweep/gallery.mp4" - }, - { - "name": "HID", - "url": "/projects/hid" - }, - { - "name": "Screen", - "url": "/projects/screen", - "imageUrl": "/static/projects/screen/console/gallery.png", - "largeImageUrl": "/static/projects/screen/console/gallery.gif", - "videoUrl": "/static/projects/screen/console/gallery.mp4" - }, - { - "name": "Accelerometer", - "url": "/projects/accelerometer", - "imageUrl": "/static/projects/accelerometer/shake/gallery.png", - "largeImageUrl": "/static/projects/accelerometer/shake/gallery.gif", - "videoUrl": "/static/projects/accelerometer/shake/gallery.mp4" - }, - { - "name": "Serial", - "url": "/projects/serial" - }, - { - "name": "Storage", - "url": "/projects/storage" - }, - { - "name": "LCD", - "url": "/projects/lcd", - "imageUrl": "/static/projects/lcd/hello-world/gallery.png", - "largeImageUrl": "/static/projects/lcd/hello-world/gallery.gif", - "videoUrl": "/static/projects/lcd/hello-world/gallery.mp4" - }, - { - "name": "LoRa", - "url": "/projects/lora" - }, - { - "name": "Power", - "url": "/projects/power" - }, - { - "name": "Bit Radio", - "url": "/projects/radio" - }, - { - "name": "Boards", - "url": "/boards", - "imageUrl": "/static/libs/adafruit-circuit-playground-express.jpg" } ] ``` ## See Also -[Jacdac](/boards/jacdac), +[Parole](/projects/parole), +[Hanukkah](/projects/hanukkah), +[Christmas](/projects/christmas), +[Kwanzaa](/projects/kwanzaa), +[My Gallery](/projects/my-gallery), [Adafruit](/boards/adafruit), -[Arduino](/boards/arduino), -[SparkFun](/boards/sparkfun), -[XinaBox](/boards/xinabox), -[Misc](/boards/misc), -[Digital IO](/projects/digital-io), -[Analog IO](/projects/analog-io), -[Pixel](/projects/pixel), -[Light](/projects/light), -[Music](/projects/music), -[Servos](/projects/servos), -[HID](/projects/hid), -[Screen](/projects/screen), -[Accelerometer](/projects/accelerometer), -[Serial](/projects/serial), -[Storage](/projects/storage), -[LCD](/projects/lcd), -[LoRa](/projects/lora), -[Power](/projects/power), -[Bit Radio](/projects/radio), -[Boards](/boards) \ No newline at end of file +[Analog IO](/projects/analog-io) \ No newline at end of file diff --git a/docs/projects/SUMMARY.md b/docs/projects/SUMMARY.md index 6a3d69f2..428e18e9 100644 --- a/docs/projects/SUMMARY.md +++ b/docs/projects/SUMMARY.md @@ -1,11 +1,42 @@ # Projects -* [Jacdac](/boards/jacdac) - * [MSR Jacdac IoT Brain 48 (ESP32-S2)](/boards/jacdac-iot-s2) - * [MSR Jacdac Brain RP2040 59](/boards/jacdac-brain-rp2040) - * [MSR Jacdac Brain F4 41](/boards/jacdac-brain-f4) - * [MSR Jacdac NRF52833 High Power 32](/boards/jacdac-nrfbrain) +* [Parole](/projects/parole) + * [ex1](/projects/parole/ex1) + * [ex2](/projects/parole/ex2) + * [ex3](/projects/parole/ex3) + * [ex4](/projects/parole/ex4) + * [ex5](/projects/parole/ex5) + * [ex6](/projects/parole/ex6) + * [ex7](/projects/parole/ex7) +* [Hanukkah](/projects/hanukkah) + * [ex1](/projects/hanukkah/ex1) + * [ex2](/projects/hanukkah/ex2) + * [ex3](/projects/hanukkah/ex3) + * [ex4](/projects/hanukkah/ex4) + * [ex5](/projects/hanukkah/ex5) + * [ex6](/projects/hanukkah/ex6) + * [ex7](/projects/hanukkah/ex7) +* [Christmas](/projects/christmas) + * [ex1](/projects/christmas/ex1) + * [ex2](/projects/christmas/ex2) + * [ex3](/projects/christmas/ex3) + * [ex4](/projects/christmas/ex4) + * [ex5](/projects/christmas/ex5) + * [ex6](/projects/christmas/ex6) + * [ex7](/projects/christmas/ex7) +* [Kwanzaa](/projects/kwanzaa) + * [ex1](/projects/kwanzaa/ex1) + * [ex2](/projects/kwanzaa/ex2) + * [ex3](/projects/kwanzaa/ex3) + * [ex4](/projects/kwanzaa/ex4) + * [ex5](/projects/kwanzaa/ex5) + * [ex6](/projects/kwanzaa/ex6) + * [ex7](/projects/kwanzaa/ex7) +* [My Gallery](/projects/my-gallery) + * [Blinking LED](/projects/my-gallery/blinking) + * [Temperature Sensor](/projects/my-gallery/temp) + * [Servo Control](/projects/my-gallery/servo) * [Adafruit](/boards/adafruit) * [Adafruit Metro M0 Express](/boards/adafruit-metro-m0-express) * [Adafruit Feather M0 Express](/boards/adafruit-feather-m0-express) @@ -19,86 +50,7 @@ * [Adafruit Feather Bluefruit NRF52840](/boards/adafruit-feather-nrf52840-express) * [Adafruit ItsyBitsy NRF52840 Express](/boards/adafruit-itsybitsy-nrf52840-express) * [Adafruit Circuit Playground Bluefruit](/boards/adafruit-circuit-playground-bluefruit) -* [Arduino](/boards/arduino) - * [Arduino MKR](/boards/arduino-mkr1000) - * [Arduino Zero](/boards/arduino-zero) - * [Arduino MKR1300](/boards/arduino-mkr1300) - * [Arduino MKR1010](/boards/arduino-mkr1010) - * [Arduino Nano 33 BLE Sense](/boards/arduino-nano-33-ble-sense) -* [SparkFun](/boards/sparkfun) - * [Sparkfun RedBoard Turbo](/boards/sparkfun-redboard-turbo) - * [Sparkfun LumiDrive](/boards/sparkfun-lumidrive) - * [Sparkfun SAMD21 Dev Breakout](/boards/sparkfun-samd21-dev-breakout) - * [Sparkfun SAMD21 Mini Breakout](/boards/sparkfun-samd21-mini-breakout) -* [XinaBox](/boards/xinabox) - * [XinaBox CC03](/boards/xinabox-cc03) - * [XinaBox CS11](/boards/xinabox-cs11) -* [Misc](/boards/misc) - * [Robotics Masters Robo HAT MM1 M4](/boards/robotics-masters-robohatmm1-m4) - * [Espressif ESP32 DevKit-C](/boards/espressif-esp32-devkit-c) - * [Raspberry Pi Pico RP2040](/boards/rpi-pico) - * [RedBear BLE NANO 2](/boards/redbear-ble-nano) - * [StichKit](/boards/stitchkit) - * [Bluebird](/boards/teknikio-bluebird) - * [Brain NRF5840](/boards/brain-nrf52840) - * [Atisa Menorah](/boards/atisa-menorah) - * [Add a new board](/boards/add-a-new-board) -* [Digital IO](/projects/digital-io) - * [Blinky](/projects/digital-io/blinky) - * [Button LED](/projects/digital-io/button-led) - * [Switch LED](/projects/digital-io/switch-led) - * [Multi Blinky](/projects/digital-io/multi-blinky) * [Analog IO](/projects/analog-io) * [Blink to Light](/projects/analog-io/blink-to-light) * [Glowy](/projects/analog-io/glowy) * [Glow Light](/projects/analog-io/glow-light) -* [Pixel](/projects/pixel) - * [Blinky](/projects/pixel/blinky) -* [Light](/projects/light) - * [Rainbow](/projects/light/rainbow) - * [Range](/projects/light/range) -* [Music](/projects/music) - * [Play Sound](/projects/music/play-sound) - * [Piano Buttons](/projects/music/piano-buttons) -* [Servos](/projects/servos) - * [Sweep](/projects/servos/sweep) - * [Buttons](/projects/servos/buttons) -* [HID](/projects/hid) - * [Keyboard](/projects/hid/keyboard) - * [Gamepad](/projects/hid/gamepad) - * [Mouse](/projects/hid/mouse) -* [Screen](/projects/screen) - * [Console](/projects/screen/console) - * [Graph](/projects/screen/graph) -* [Accelerometer](/projects/accelerometer) - * [Shake](/projects/accelerometer/shake) - * [Level](/projects/accelerometer/level) - * [Log Values](/projects/accelerometer/log-values) -* [Serial](/projects/serial) - * [console](/projects/serial/console) - * [write-data](/projects/serial/write-data) - * [read-data](/projects/serial/read-data) - * [custom](/projects/serial/custom) -* [Storage](/projects/storage) - * [write file](/projects/storage/write-file) - * [data logging](/projects/storage/data-logger) -* [LCD](/projects/lcd) - * [Hello World](/projects/lcd/hello-world) -* [LoRa](/projects/lora) - * [Sender](/projects/lora/sender) - * [Receiver](/projects/lora/receiver) -* [Power](/projects/power) - * [Deep Sleep](/projects/power/deep-sleep) - * [Poke](/projects/power/poke) -* [Bit Radio](/projects/radio) - * [Send Number](/projects/radio/send-number) - * [Send String](/projects/radio/send-string) -* [Boards](/boards) - * [Adafruit](/boards/adafruit) - * [Arduino](/boards/arduino) - * [Sparkfun](/boards/sparkfun) - * [Jacdac](/boards/jacdac) - * [XinaBox](/boards/xinabox) - * [Misc](/boards/misc) - * [Atisa Menorah](/boards/atisa-menorah) - * [Add your board](/boards/add-a-new-board) diff --git a/docs/projects/christmas.md b/docs/projects/christmas.md new file mode 100644 index 00000000..9514f75c --- /dev/null +++ b/docs/projects/christmas.md @@ -0,0 +1,73 @@ +# My Gallery + +## Tutorials + +### ~ codecard + +* name: ex1 +* url: /projects/christmas/ex1 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + + +--- + +* name: ex2 +* url: /projects/christmas/ex2 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex3 +* url: /projects/christmas/ex3 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex4 +* url: /projects/christmas/ex4 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex5 +* url: /projects/christmas/ex5 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex6 +* url: /projects/christmas/ex6 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex7 +* url: /projects/christmas/ex7 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +### ~ + + +## See Also + +[ex1](/projects/christmas/ex1), +[ex2](/projects/christmas/ex2), +[ex3](/projects/christmas/ex3), +[ex4](/projects/christmas/ex4), +[ex5](/projects/christmas/ex5), +[ex6](/projects/christmas/ex6), +[ex7](/projects/christmas/ex7) \ No newline at end of file diff --git a/docs/projects/christmas/ex1.md b/docs/projects/christmas/ex1.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex1.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex2.md b/docs/projects/christmas/ex2.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex2.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex3.md b/docs/projects/christmas/ex3.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex3.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex4.md b/docs/projects/christmas/ex4.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex4.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex5.md b/docs/projects/christmas/ex5.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex5.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex6.md b/docs/projects/christmas/ex6.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex6.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/christmas/ex7.md b/docs/projects/christmas/ex7.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/christmas/ex7.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah.md b/docs/projects/hanukkah.md new file mode 100644 index 00000000..7f39d566 --- /dev/null +++ b/docs/projects/hanukkah.md @@ -0,0 +1,73 @@ +# My Gallery + +## Tutorials + +### ~ codecard + +* name: ex1 +* url: /projects/hanukkah/ex1 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + + +--- + +* name: ex2 +* url: /projects/hanukkah/ex2 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex3 +* url: /projects/hanukkah/ex3 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex4 +* url: /projects/hanukkah/ex4 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex5 +* url: /projects/hanukkah/ex5 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex6 +* url: /projects/hanukkah/ex6 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex7 +* url: /projects/hanukkah/ex7 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +### ~ + + +## See Also + +[ex1](/projects/hanukkah/ex1), +[ex2](/projects/hanukkah/ex2), +[ex3](/projects/hanukkah/ex3), +[ex4](/projects/hanukkah/ex4), +[ex5](/projects/hanukkah/ex5), +[ex6](/projects/hanukkah/ex6), +[ex7](/projects/hanukkah/ex7) \ No newline at end of file diff --git a/docs/projects/hanukkah/ex1.md b/docs/projects/hanukkah/ex1.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex1.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex2.md b/docs/projects/hanukkah/ex2.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex2.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex3.md b/docs/projects/hanukkah/ex3.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex3.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex4.md b/docs/projects/hanukkah/ex4.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex4.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex5.md b/docs/projects/hanukkah/ex5.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex5.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex6.md b/docs/projects/hanukkah/ex6.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex6.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/hanukkah/ex7.md b/docs/projects/hanukkah/ex7.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/hanukkah/ex7.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa.md b/docs/projects/kwanzaa.md new file mode 100644 index 00000000..d1c7527b --- /dev/null +++ b/docs/projects/kwanzaa.md @@ -0,0 +1,73 @@ +# My Gallery + +## Tutorials + +### ~ codecard + +* name: ex1 +* url: /projects/kwanzaa/ex1 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + + +--- + +* name: ex2 +* url: /projects/kwanzaa/ex2 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex3 +* url: /projects/kwanzaa/ex3 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex4 +* url: /projects/kwanzaa/ex4 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex5 +* url: /projects/kwanzaa/ex5 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex6 +* url: /projects/kwanzaa/ex6 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex7 +* url: /projects/kwanzaa/ex7 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +### ~ + + +## See Also + +[ex1](/projects/kwanzaa/ex1), +[ex2](/projects/kwanzaa/ex2), +[ex3](/projects/kwanzaa/ex3), +[ex4](/projects/kwanzaa/ex4), +[ex5](/projects/kwanzaa/ex5), +[ex6](/projects/kwanzaa/ex6), +[ex7](/projects/kwanzaa/ex7) \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex1.md b/docs/projects/kwanzaa/ex1.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex1.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex2.md b/docs/projects/kwanzaa/ex2.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex2.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex3.md b/docs/projects/kwanzaa/ex3.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex3.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex4.md b/docs/projects/kwanzaa/ex4.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex4.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex5.md b/docs/projects/kwanzaa/ex5.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex5.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex6.md b/docs/projects/kwanzaa/ex6.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex6.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/kwanzaa/ex7.md b/docs/projects/kwanzaa/ex7.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/kwanzaa/ex7.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/my-gallery.md b/docs/projects/my-gallery.md new file mode 100644 index 00000000..38264a5b --- /dev/null +++ b/docs/projects/my-gallery.md @@ -0,0 +1,43 @@ + +# My Gallery + +## Tutorials + +### ~ codecard + +* name: Blinking LED +* url: /projects/my-gallery/blinking +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* description: Learn to blink an LED +* youTubeId: Yw6u6YkTgQ4 + + +--- + +* name: Temperature Sensor +* url: /projects/my-gallery/temp +* cardType: tutorial +* imageUrl: /static/projects/digital-io/button-led/gallery.png +* description: example 2 + + +--- + +* name: Servo Control +* url: /projects/my-gallery/servo +* cardType: tutorial +* imageUrl: /static/projects/analog-io/blink-to-light/gallery.png +* largeImageUrl: /static/projects/analog-io/blink-to-light/gallery.gif +* videoUrl: /static/projects/analog-io/blink-to-light/gallery.mp4 +* description: Learn about analog read + + +### ~ + + +## See Also + +[Blinking LED](/projects/my-gallery/blinking), +[Servo Control](/projects/my-gallery/servo), +[Temperature Sensor](/projects/my-gallery/temp) \ No newline at end of file diff --git a/docs/projects/my-gallery/blinking.md b/docs/projects/my-gallery/blinking.md new file mode 100644 index 00000000..fe46efed --- /dev/null +++ b/docs/projects/my-gallery/blinking.md @@ -0,0 +1,29 @@ + +# Blinking LED + +You can have multiple forever loops running concurrently to blink multiple LEDs. + +```template +forever(function() { + pins.D0.digitalWrite(false) + pause(100) + pins.D0.digitalWrite(true) + pause(100) +}) +forever(function() { + pins.D1.digitalWrite(false) + pause(500) + pins.D1.digitalWrite(true) + pause(500) +}) +``` + +```package +adafruit-trinket-m0 +``` + +```config +feature=uf2 +feature=pind0 +feature=pind1 +``` \ No newline at end of file diff --git a/docs/projects/my-gallery/servo.md b/docs/projects/my-gallery/servo.md new file mode 100644 index 00000000..d651160e --- /dev/null +++ b/docs/projects/my-gallery/servo.md @@ -0,0 +1,48 @@ +# Blink to Light + +## Introduction @unplugged + +Blink an LED where the tempo is controlled by a light sensor. + +![An LED blinking based on a light sensor](/static/projects/analog-io/blink-to-light/gallery.gif) + +## Step 1 @fullscreen + +Add the code to drives a **blinking LED** on pin **D0**. + +```template +forever(function () { + pins.D0.digitalWrite(true) + pause(100) + pins.D0.digitalWrite(false) + pause(100) +}) +``` + +## Step 2 @fullscreen + +Insert a ``||pins:analog read||`` block for **A0** in the first ``||loops:pause||`` block. +The ``||pins:analog read||`` returns a value between 0 (no input) to 1023 (full input) which will be translated in milliseconds of pause. + +```blocks +forever(function () { + pins.D0.digitalWrite(true) + pause(pins.A0.analogRead()) + pins.D0.digitalWrite(false) + pause(100) +}) +``` + +## Step 3 @fullscreen + +Look at the simulator and make sure your program works as expected. + +If you have a @boardname@, press ``|Download|`` and follow the instruction to get your code on your device. + +Click on the **wrench** icon under the simulator to get detailed breadboarding instructions. + +```config +feature=uf2 +feature=pind0 +feature=pina0 +``` \ No newline at end of file diff --git a/docs/projects/my-gallery/temp.md b/docs/projects/my-gallery/temp.md new file mode 100644 index 00000000..e420bacf --- /dev/null +++ b/docs/projects/my-gallery/temp.md @@ -0,0 +1,18 @@ +# Temperature + +Some text here. + +```blocks +forever(function() { + pins.D0.digitalWrite(false) + pause(100) + pins.D0.digitalWrite(true) + pause(100) +}) +``` + +```config +feature=uf2 +feature=pind0 +feature=pind1 +``` \ No newline at end of file diff --git a/docs/projects/parole.md b/docs/projects/parole.md new file mode 100644 index 00000000..e8ca37f5 --- /dev/null +++ b/docs/projects/parole.md @@ -0,0 +1,73 @@ +# My Gallery + +## Tutorials + +### ~ codecard + +* name: ex1 +* url: /projects/parole/ex1 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + + +--- + +* name: ex2 +* url: /projects/parole/ex2 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex3 +* url: /projects/parole/ex3 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex4 +* url: /projects/parole/ex4 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex5 +* url: /projects/parole/ex5 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex6 +* url: /projects/parole/ex6 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +--- + +* name: ex7 +* url: /projects/parole/ex7 +* cardType: tutorial +* imageUrl: /static/projects/digital-io/blinky/gallery.png +* youTubeId: Yw6u6YkTgQ4 + +### ~ + + +## See Also + +[ex1](/projects/parole/ex1), +[ex2](/projects/parole/ex2), +[ex3](/projects/parole/ex3), +[ex4](/projects/parole/ex4), +[ex5](/projects/parole/ex5), +[ex6](/projects/parole/ex6), +[ex7](/projects/parole/ex7) \ No newline at end of file diff --git a/docs/projects/parole/ex1.md b/docs/projects/parole/ex1.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex1.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex2.md b/docs/projects/parole/ex2.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex2.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex3.md b/docs/projects/parole/ex3.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex3.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex4.md b/docs/projects/parole/ex4.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex4.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex5.md b/docs/projects/parole/ex5.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex5.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex6.md b/docs/projects/parole/ex6.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex6.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/docs/projects/parole/ex7.md b/docs/projects/parole/ex7.md new file mode 100644 index 00000000..e5dea527 --- /dev/null +++ b/docs/projects/parole/ex7.md @@ -0,0 +1,9 @@ +# ex + +This is just some text you can put here. + +```sim +forever(function() { + +}) +``` \ No newline at end of file diff --git a/targetconfig.json b/targetconfig.json index 758acdac..d20c2471 100644 --- a/targetconfig.json +++ b/targetconfig.json @@ -45,27 +45,12 @@ } }, "galleries": { - "Jacdac": "/boards/jacdac", + "Parole": "/projects/parole", + "Hanukkah": "/projects/hanukkah", + "Christmas": "/projects/christmas", + "Kwanzaa": "/projects/kwanzaa", + "My Gallery": "/projects/my-gallery", "Adafruit": "/boards/adafruit", - "Arduino": "/boards/arduino", - "SparkFun": "/boards/sparkfun", - "XinaBox": "/boards/xinabox", - "Misc": "/boards/misc", - "Digital IO": "/projects/digital-io", - "Analog IO": "/projects/analog-io", - "Pixel": "/projects/pixel", - "Light": "/projects/light", - "Music": "/projects/music", - "Servos": "/projects/servos", - "HID": "/projects/hid", - "Screen": "/projects/screen", - "Accelerometer": "/projects/accelerometer", - "Serial": "/projects/serial", - "Storage": "/projects/storage", - "LCD": "/projects/lcd", - "LoRa": "/projects/lora", - "Power": "/projects/power", - "Bit Radio": "/projects/radio", - "Boards": "/boards" + "Analog IO": "/projects/analog-io" } } From 0ebdaa27f94c28905db5e061ce5fd9aaf0345b07 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 30 Jun 2025 17:23:35 -0700 Subject: [PATCH 06/19] added custom image, not to spec && updated trinket svg --- libs/adafruit-trinket-m0/board.svg | 2 -- libs/atisa-menorah/board.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libs/adafruit-trinket-m0/board.svg b/libs/adafruit-trinket-m0/board.svg index e3ff83a6..c37f7cc1 100644 --- a/libs/adafruit-trinket-m0/board.svg +++ b/libs/adafruit-trinket-m0/board.svg @@ -291,8 +291,6 @@ - - diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index eb65f2e4..7b885f52 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -147,4 +147,4 @@ "MISO": "MISO", "SCK": "SCK" } -} \ No newline at end of file +} From 7b567b573dab6bbe58e4e2904591f312aced26ea Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 14 Jul 2025 09:10:04 -0700 Subject: [PATCH 07/19] updated candles to be LED elements --- libs/atisa-menorah/board.json | 60 +- libs/atisa-menorah/board.svg.backup | 682 +++ libs/atisa-menorah/fritzing-board_view.svg | 4928 -------------------- sim/visuals/board-windsurf.ts.old | 419 ++ sim/visuals/board.ts | 96 +- 5 files changed, 1245 insertions(+), 4940 deletions(-) create mode 100644 libs/atisa-menorah/board.svg.backup delete mode 100644 libs/atisa-menorah/fritzing-board_view.svg create mode 100644 sim/visuals/board-windsurf.ts.old diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 7b885f52..d03c000c 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -90,7 +90,65 @@ } ], "touchPads": [], - "buttons": [] + "buttons": [], + "candles": [ + { + "id": "candle1", + "x": 100, + "y": 200, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle2", + "x": 140, + "y": 180, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle3", + "x": 180, + "y": 160, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle4", + "x": 220, + "y": 140, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle5", + "x": 260, + "y": 160, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle6", + "x": 300, + "y": 180, + "r": 15, + "color": "#ffffff" + }, + { + "id": "candle7", + "x": 340, + "y": 200, + "r": 15, + "color": "#ffffff" + }, + { + "id": "shamash", + "x": 220, + "y": 220, + "r": 12, + "color": "#ffcc00" + } + ] }, "gpioPinMap": { "VBAT": "VBAT", diff --git a/libs/atisa-menorah/board.svg.backup b/libs/atisa-menorah/board.svg.backup new file mode 100644 index 00000000..4dd6f89e --- /dev/null +++ b/libs/atisa-menorah/board.svg.backup @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/atisa-menorah/fritzing-board_view.svg b/libs/atisa-menorah/fritzing-board_view.svg deleted file mode 100644 index e80ce547..00000000 --- a/libs/atisa-menorah/fritzing-board_view.svg +++ /dev/null @@ -1,4928 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - 1 - - - 5 - - - 5 - - - 10 - - - 10 - - - 15 - - - 15 - - - 20 - - - 20 - - - 25 - - - 25 - - - 30 - - - 30 - - - 35 - - - 35 - - - 40 - - - 40 - - - 45 - - - 45 - - - 50 - - - 50 - - - 55 - - - 55 - - - 60 - - - 60 - - - A - - - A - - - B - - - B - - - C - - - C - - - D - - - D - - - E - - - E - - - F - - - F - - - G - - - G - - - H - - - H - - - I - - - I - - - J - - - J - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +5V - - - - - - - - - - - - - - - - - - - - - - - - - GND - - - - - - - - - - - - - - - - - - - - - - - - - GND - - - - - - - - - - - - - - - - - - - - - - - - - +5V - - - - - - - - - - - - - - - - - - - - - - - - - Din - - - - - - - - - - - - - - - - - - - - - - - - - Dout - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +5V - - - - - - - - - - - - - - - - - - - - - - - - - GND - - - - - - - - - - - - - - - - - - - - - - - - - GND - - - - - - - - - - - - - - - - - - - - - - - - - +5V - - - - - - - - - - - - - - - - - - - - - - - - - Din - - - - - - - - - - - - - - - - - - - - - - - - - Dout - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sim/visuals/board-windsurf.ts.old b/sim/visuals/board-windsurf.ts.old new file mode 100644 index 00000000..108a8ac5 --- /dev/null +++ b/sim/visuals/board-windsurf.ts.old @@ -0,0 +1,419 @@ +// SVG +``` + + + + + + + + + +``` + +// In board.ts, update the MetroBoardSvg class +export class MetroBoardSvg extends GenericBoardSvg { + public board: pxsim.DalBoard; + private onBoardLeds: BoardLed[]; + private onBoardNeopixels: BoardNeopixel[]; + private onBoardReset: BoardResetButton; + private onBoardButtons: BoardButton[]; + private onBoardTouchPads: BoardTouchButton[]; + private candleElements: SVGGElement[] = []; + private flameElements: SVGGElement[] = []; + private candleGlowFilter: SVGFilterElement; + + constructor(public props: MetroBoardProps) { + super(props); + + const el = this.getView().el; + this.addDefs(el); + + this.onBoardLeds = []; + this.onBoardNeopixels = []; + this.onBoardTouchPads = []; + this.onBoardButtons = []; + + // Initialize candle elements + this.initializeCandles(el); + + if (props && props.theme) + this.updateTheme(); + + if (props && props.runtime) { + this.board = this.props.runtime.board as pxsim.DalBoard; + this.board.updateSubscribers.push(() => this.updateState()); + this.updateState(); + } + } + + private initializeCandles(el: SVGElement) { + // Add glow filter for candle flames + const defs = svg.child(el, "defs", {}); + this.candleGlowFilter = svg.child(defs, "filter", { + id: "candleGlow", + x: "-50%", y: "-50%", width: "200%", height: "200%" + }) as SVGFilterElement; + svg.child(this.candleGlowFilter, "feGaussianBlur", { + stdDeviation: "4", + result: "coloredBlur" + }); + const feMerge = svg.child(this.candleGlowFilter, "feMerge", {}); + svg.child(feMerge, "feMergeNode", { in: "coloredBlur" }); + svg.child(feMerge, "feMergeNode", { in: "SourceGraphic" }); + + // Find and store candle elements + for (let i = 0; i < 9; i++) { // Assuming 9 candles for Hanukkah + const candleGroup = el.querySelector(`#candle${i}`) as SVGGElement; + if (candleGroup) { + this.candleElements[i] = candleGroup; + this.flameElements[i] = candleGroup.querySelector('.flame') as SVGGElement; + } + } + } + + private updateState() { + if (!this.board) return; + + // Update regular components + this.onBoardLeds.forEach(led => led.updateState()); + this.onBoardNeopixels.forEach(pixel => pixel.updateState()); + this.onBoardButtons.forEach(btn => btn.updateState()); + this.onBoardTouchPads.forEach(tp => tp.updateState()); + + // Update candle states + this.updateCandles(); + } + + private updateCandles() { + if (!this.board) return; + + // Get neopixel state + const neopixelPin = this.board.defaultNeopixelPin(); + if (!neopixelPin) return; + + const neopixelState = this.board.tryGetNeopixelState(neopixelPin.id); + if (!neopixelState) return; + + // Update each candle + for (let i = 0; i < 9; i++) { + const candle = this.candleElements[i]; + const flame = this.flameElements[i]; + if (!candle || !flame) continue; + + // Get color from neopixel (wrapping around if fewer pixels than candles) + const rgb = neopixelState.pixelColor(i % neopixelState.length); + + if (!rgb || (rgb[0] === 0 && rgb[1] === 0 && rgb[2] === 0)) { + // Candle is off + svg.fill(flame, 'none'); + svg.fill(candle, '#FFFFFF'); // Default candle color + continue; + } + + // Convert RGB to HSL for better color manipulation + const [h, s, l] = visuals.rgbToHsl([rgb[0], rgb[1], rgb[2]]); + + // Make flame brighter and more vibrant + const flameL = Math.max(l * 1.5, 85); + const flameS = Math.min(s * 1.2, 100); + const flameH = (h + 10) % 360; // Slight hue shift for more natural flame + + // Apply flame color with glow + svg.fill(flame, `hsl(${flameH}, ${flameS}%, ${flameL}%)`); + svg.filter(flame, 'url(#candleGlow)'); + + // Make candle body a dimmer, less saturated version + const candleL = l * 0.6; + const candleS = s * 0.5; + svg.fill(candle, `hsl(${h}, ${candleS}%, ${candleL}%)`); + } + } + + // ... rest of the class remains the same +} + +/// + +// In board.ts, update the MetroBoardSvg class + +// Add these imports at the top of the file if not already present +import { svg } from "./svg_util"; +import { visuals } from "./visuals"; + +// ... existing code ... + +export class MetroBoardSvg extends GenericBoardSvg { + public board: pxsim.DalBoard; + private onBoardLeds: BoardLed[]; + private onBoardNeopixels: BoardNeopixel[]; + private onBoardReset: BoardResetButton; + private onBoardButtons: BoardButton[]; + private onBoardTouchPads: BoardTouchButton[]; + private candleElements: SVGGElement[] = []; + private flameElements: SVGGElement[] = []; + private candleGlowFilter: SVGFilterElement; + + constructor(public props: MetroBoardProps) { + super(props); + + const el = this.getView().el; + this.addDefs(el); + this.initializeCandles(el); + + this.onBoardLeds = []; + this.onBoardNeopixels = []; + this.onBoardTouchPads = []; + this.onBoardButtons = []; + + if (props && props.theme) + this.updateTheme(); + + if (props && props.runtime) { + this.board = this.props.runtime.board as pxsim.DalBoard; + this.board.updateSubscribers.push(() => this.updateState()); + this.updateState(); + } + } + + private initializeCandles(el: SVGElement) { + // Add glow filter for candle flames + const defs = el.querySelector('defs') || svg.child(el, 'defs', {}); + + // Only add the glow filter if it doesn't exist + if (!el.querySelector('#candleGlow')) { + this.candleGlowFilter = svg.child(defs, "filter", { + id: "candleGlow", + x: "-50%", y: "-50%", + width: "200%", + height: "200%" + }) as SVGFilterElement; + + const feGaussianBlur = svg.child(this.candleGlowFilter, "feGaussianBlur", { + stdDeviation: "4", + result: "coloredBlur" + }); + + const feMerge = svg.child(this.candleGlowFilter, "feMerge", {}); + svg.child(feMerge, "feMergeNode", { in: "coloredBlur" }); + svg.child(feMerge, "feMergeNode", { in: "SourceGraphic" }); + } + + // Find and store candle elements + for (let i = 0; i < 9; i++) { // 9 candles for Hanukkah + const candleId = `candle${i}`; + const candleGroup = el.querySelector(`#${candleId}`) as SVGGElement; + + if (candleGroup) { + this.candleElements[i] = candleGroup; + + // Look for flame element (either direct child or nested) + let flame = candleGroup.querySelector('.flame') as SVGGElement; + if (!flame) { + // If no flame element exists, create one + flame = svg.child(candleGroup, 'g', { class: 'flame' }); + // Add a simple flame shape if none exists + if (!flame.querySelector('path, circle')) { + svg.child(flame, 'path', { + d: 'M-3,-10 L0,-20 L3,-10 Q0,-15 -3,-10', + fill: 'none', + stroke: 'none' + }); + } + } + this.flameElements[i] = flame; + } + } + } + + private updateState() { + if (!this.board) return; + + // Update regular components + this.onBoardLeds.forEach(led => led.updateState()); + this.onBoardNeopixels.forEach(pixel => pixel.updateState()); + this.onBoardButtons.forEach(btn => btn.updateState()); + this.onBoardTouchPads.forEach(tp => tp.updateState()); + + // Update candle states + this.updateCandles(); + } + + private updateCandles() { + if (!this.board) return; + + // Get neopixel state + const neopixelPin = this.board.defaultNeopixelPin(); + if (!neopixelPin) return; + + const neopixelState = this.board.tryGetNeopixelState(neopixelPin.id); + if (!neopixelState) return; + + // Update each candle + for (let i = 0; i < 9; i++) { + const candle = this.candleElements[i]; + const flame = this.flameElements[i]; + if (!candle || !flame) continue; + + // Get color from neopixel (wrapping around if fewer pixels than candles) + const rgb = neopixelState.pixelColor(i % neopixelState.length); + + if (!rgb || (rgb[0] === 0 && rgb[1] === 0 && rgb[2] === 0)) { + // Candle is off + svg.fill(flame, 'none'); + svg.fill(candle, '#FFFFFF'); // Default candle color + flame.style.display = 'none'; + continue; + } + + // Make flame visible + flame.style.display = ''; + + // Convert RGB to HSL for better color manipulation + const [h, s, l] = visuals.rgbToHsl([rgb[0], rgb[1], rgb[2]]); + + // Make flame brighter and more vibrant + const flameL = Math.max(l * 1.5, 85); + const flameS = Math.min(s * 1.2, 100); + const flameH = (h + 10) % 360; // Slight hue shift for more natural flame + + // Apply flame color with glow + const flameColor = `hsl(${flameH}, ${flameS}%, ${flameL}%)`; + flame.querySelectorAll('path, circle').forEach((el: SVGElement) => { + svg.fill(el, flameColor); + svg.stroke(el, `hsla(${flameH}, ${flameS}%, ${Math.min(flameL * 1.2, 100)}%, 0.7)`); + }); + + // Make candle body a dimmer, less saturated version + const candleL = l * 0.6; + const candleS = s * 0.5; + candle.querySelectorAll('.candle-body, rect, path:not(.flame *)').forEach((el: SVGElement) => { + if (!flame.contains(el)) { // Don't style flame elements + svg.fill(el, `hsl(${h}, ${candleS}%, ${candleL}%)`); + } + }); + } + } + + // ... rest of the existing methods ... +} + +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 8dc07b61..24bd9afd 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -272,27 +272,101 @@ namespace pxsim.visuals { } } + interface CandleDefinition { + id: string; + x: number; + y: number; + r: number; + color: string; + } + + interface BoardVisualDefinition extends BoardImageDefinition { + candles?: CandleDefinition[]; + } + class BoardNeopixel { name: string; - element: SVGCircleElement; + element: SVGGElement; + private candles: {element: SVGCircleElement, defaultColor: string}[] = []; constructor(name: string, x: number, y: number, r: number) { this.name = name; - this.element = svg.elt("circle", { cx: x + r / 2, cy: y + r / 2, r: 10 }) as SVGCircleElement - svg.title(this.element, name); + this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; + + // Create the main neopixel element (kept for backward compatibility) + const mainPixel = svg.elt("circle", { + cx: x + r / 2, + cy: y + r / 2, + r: 10, + style: "display: none" // Hide the original neopixel + }) as SVGCircleElement; + this.element.appendChild(mainPixel); + + // Create candle elements if we're on the Atisa Menorah board + const board = (window as any).board as pxsim.DalBoard; + if (board?.boardDefinition?.visual) { + const visualDef = board.boardDefinition.visual as BoardVisualDefinition; + if (visualDef.candles) { + this.createCandles(visualDef.candles); + } + } + } + + private createCandles(candleDefs: CandleDefinition[]) { + for (const candleDef of candleDefs) { + const candle = svg.elt("circle", { + cx: candleDef.x, + cy: candleDef.y, + r: candleDef.r, + fill: candleDef.color, + class: `candle ${candleDef.id}` + }) as SVGCircleElement; + + // Add glow effect to candles + svg.filter(candle, `url(#neopixelglow)`); + + this.candles.push({ + element: candle, + defaultColor: candleDef.color + }); + + this.element.appendChild(candle); + } } setColor(rgb: [number, number, number]) { + if (!this.candles.length) { + // Fallback to original behavior if no candles + const hsl = visuals.rgbToHsl(rgb); + const [h, s, l] = hsl; + const lx = Math.max(l * 1.3, 85); + + this.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)`; + this.element.style.strokeWidth = "1.5"; + svg.fill(this.element, `hsl(${h}, ${s}%, ${lx}%)`); + svg.filter(this.element, `url(#neopixelglow)`); + return; + } + + // For the Menorah, we'll set all candles to the same color for now + // In the future, we could map different neopixel indices to different candles const hsl = visuals.rgbToHsl(rgb); - let [h, s, l] = hsl; + const [h, s, l] = hsl; const lx = Math.max(l * 1.3, 85); - - // at least 10% luminosity - l = l * 90 / 100 + 10; - this.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)` - this.element.style.strokeWidth = "1.5"; - svg.fill(this.element, `hsl(${h}, ${s}%, ${lx}%)`); - svg.filter(this.element, `url(#neopixelglow)`); + + for (const candle of this.candles) { + // For the shamash, we might want to keep its original color + const isShamash = (candle.element.getAttribute('class') || '').includes('shamash'); + if (isShamash) { + // Optionally keep shamash color or apply a different effect + // For now, we'll keep its original color + continue; + } + + candle.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)`; + candle.element.style.strokeWidth = "1.5"; + svg.fill(candle.element, `hsl(${h}, ${s}%, ${lx}%)`); + } } } From 5b8122f641e12cb994685dfde342946fa157df91 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:02:38 -0700 Subject: [PATCH 08/19] checkpoint before ledmatrix-inspired build --- libs/adafruit-trinket-m0/board.svg | 2 + libs/atisa-menorah/board.json | 64 +-- libs/atisa-menorah/board.svg | 18 +- libs/atisa-menorah/boardhd.svg | 28 +- libs/atisa-menorah/config.ts | 17 +- maker.code-workspace | 6 + sim/visuals/board.ts.old | 697 +++++++++++++++++++++++++++++ sim/visuals/led-candles.ts | 135 ++++++ 8 files changed, 912 insertions(+), 55 deletions(-) create mode 100644 sim/visuals/board.ts.old create mode 100644 sim/visuals/led-candles.ts diff --git a/libs/adafruit-trinket-m0/board.svg b/libs/adafruit-trinket-m0/board.svg index c37f7cc1..e3ff83a6 100644 --- a/libs/adafruit-trinket-m0/board.svg +++ b/libs/adafruit-trinket-m0/board.svg @@ -291,6 +291,8 @@ + + diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index d03c000c..2e694810 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -87,67 +87,67 @@ "h": 10.056290621329891, "color": "neopixel", "label": "NEOPIXEL" - } - ], - "touchPads": [], - "buttons": [], - "candles": [ + }, { - "id": "candle1", + "id": "candle0", "x": 100, "y": 200, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL0" }, { - "id": "candle2", + "id": "candle1", "x": 140, "y": 180, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL1" }, { - "id": "candle3", + "id": "candle2", "x": 180, "y": 160, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL2" }, { - "id": "candle4", + "id": "candle3", "x": 220, "y": 140, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL3" }, { - "id": "candle5", + "id": "candle4", "x": 260, "y": 160, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL4" }, { - "id": "candle6", + "id": "candle5", "x": 300, "y": 180, "r": 15, - "color": "#ffffff" + "color": "neopixel", + "label": "NEOPIXEL5" }, { - "id": "candle7", + "id": "candle6", "x": 340, "y": 200, "r": 15, - "color": "#ffffff" - }, - { - "id": "shamash", - "x": 220, - "y": 220, - "r": 12, - "color": "#ffcc00" + "color": "neopixel", + "label": "NEOPIXEL6" } + ], + "touchPads": [], + "buttons": [], + "candles": [ ] }, "gpioPinMap": { @@ -177,8 +177,13 @@ "D0": "A2_D0_SDA", "SDA": "A2_D0_SDA", "LED": "LED", - "RESET": "RESET", - "NEOPIXEL": "NEOPIXEL" + "NEOPIXEL0": "NEOPIXEL0", + "NEOPIXEL1": "NEOPIXEL1", + "NEOPIXEL2": "NEOPIXEL2", + "NEOPIXEL3": "NEOPIXEL3", + "NEOPIXEL4": "NEOPIXEL4", + "NEOPIXEL5": "NEOPIXEL5", + "NEOPIXEL6": "NEOPIXEL6" }, "groundPins": [ "GND" @@ -192,7 +197,8 @@ "SCL": "SCL" }, "onboardComponents": [ - "pixel" + "pixel", + "neopixel" ], "marginWhenBreadboarding": [ 0, diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index 4dd6f89e..e809cc99 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -2,13 +2,13 @@ - - - - - - - + + + + + + + @@ -321,7 +321,7 @@ - + @@ -379,7 +379,7 @@ - + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg index 2bb84c2b..fdc88d3d 100644 --- a/libs/atisa-menorah/boardhd.svg +++ b/libs/atisa-menorah/boardhd.svg @@ -24,39 +24,39 @@ id="path840" /> { + return { + accent: accent, + pin: "#D4AF37", + pinTouched: "#FFA500", + pinActive: "#FF5500", + ledOn: "#ff7777", + ledOff: "#fff", + buttonOuter: "#979797", + buttonUps: ["#000", "#000", "#000"], + buttonDown: "#FFA500", + virtualButtonDown: "#FFA500", + virtualButtonOuter: "#333", + virtualButtonUp: "#fff", + lightLevelOn: "yellow", + lightLevelOff: "#555", + soundLevelOn: "#7f8c8d", + soundLevelOff: "#555", + } + }); + + export function randomTheme(): IBoardTheme { + return themes[Math.floor(Math.random() * themes.length)]; + } + + export type ComputedBoardDimensions = { + scaleFn: (n: number) => number, + height: number, + width: number, + xOff: number, + yOff: number + }; + + export function getBoardDimensions(vis: BoardImageDefinition): ComputedBoardDimensions { + let scaleFn = (n: number) => n * (PIN_DIST / vis.pinDist); + let width = scaleFn(vis.width); + return { + scaleFn: scaleFn, + height: scaleFn(vis.height), + width: width, + xOff: (VIEW_WIDTH - width) / 2.0, + yOff: TOP_MARGIN + } + } + + export interface MetroBoardProps extends GenericBoardProps { + runtime?: pxsim.Runtime; + theme?: IBoardTheme; + disableTilt?: boolean; + } + + export class MetroBoardSvg extends GenericBoardSvg { + + public board: pxsim.DalBoard; + private onBoardLeds: BoardLed[]; + private onBoardNeopixels: BoardNeopixel[]; + private onBoardReset: BoardResetButton; + private onBoardButtons: BoardButton[]; + private onBoardTouchPads: BoardTouchButton[]; + + constructor(public props: MetroBoardProps) { + super(props); + + const el = this.getView().el; + this.addDefs(el); + + this.onBoardLeds = [] + this.onBoardNeopixels = []; + this.onBoardTouchPads = []; + this.onBoardButtons = []; + + // neopixels/leds + for (const l of props.visualDef.leds || []) { + if (l.color == "neopixel") { + const onBoardNeopixel = new BoardNeopixel(l.label, l.x, l.y, l.w || 0); + this.onBoardNeopixels.push(onBoardNeopixel); + el.appendChild(onBoardNeopixel.element); + } else { + const pin = pinByName(l.label); + if (pin) { + let bl = new BoardLed(l.x, l.y, l.color, pinByName(l.label), + l.w || 9, l.h || 8) + this.onBoardLeds.push(bl) + el.appendChild(bl.element) + } + } + } + this.onBoardNeopixels.sort((l, r) => { + const li = parseInt(l.name.replace(/^[^\d]*/, '')) || 0; + const ri = parseInt(r.name.replace(/^[^\d]*/, '')) || 0; + return li < ri ? -1 : li > ri ? 1 : 0; + }) + + // reset button + if (props.visualDef.reset) { + this.onBoardReset = new BoardResetButton(props.visualDef.reset) + el.appendChild(this.onBoardReset.element) + } + + // touch pads + for (const l of props.visualDef.touchPads || []) { + const pin = pxsim.pinIds[l.label]; + if (!pin) { + console.error(`touch pin ${pin} not found`) + continue; + } + const tp = new BoardTouchButton(l, pin); + this.onBoardTouchPads.push(tp); + el.appendChild(tp.element); + } + + // regular buttons + for (const l of props.visualDef.buttons || []) { + const tp = new BoardButton(l); + this.onBoardButtons.push(tp); + el.appendChild(tp.element); + } + + if (props && props.theme) + this.updateTheme(); + + if (props && props.runtime) { + this.board = this.props.runtime.board as pxsim.DalBoard; + this.board.updateSubscribers.push(() => this.updateState()); + this.updateState(); + } + + + } + + public updateTheme() { + } + + public updateState() { + this.onBoardLeds.forEach(l => l.updateState()); + if (this.board.neopixelPin) { + const state = this.board.neopixelState(this.board.neopixelPin.id); + if (state.buffer) { + for (let i = 0; i < this.onBoardNeopixels.length; ++i) { + const rgb = state.pixelColor(i) + if (rgb !== null) + this.onBoardNeopixels[i].setColor(rgb as any); + } + } + } + } + + private addDefs(el: SVGElement) { + const defs = svg.child(el, "defs", {}); + + let neopixelglow = svg.child(defs, "filter", { id: "neopixelglow", x: "-200%", y: "-200%", width: "400%", height: "400%" }); + svg.child(neopixelglow, "feGaussianBlur", { stdDeviation: "4.3", result: "coloredBlur" }); + let neopixelmerge = svg.child(neopixelglow, "feMerge", {}); + svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }) + svg.child(neopixelmerge, "feMergeNode", { in: "SourceGraphic" }) + + const style = svg.child(el, "style", {}); + style.textContent = STYLE; + } + } + + class BoardResetButton { + element: SVGElement; + constructor(p: BoxDefinition) { + p.w = p.w || 15; + p.h = p.h || 15; + this.element = svg.elt("circle", { + cx: p.x + p.w / 2, + cy: p.y + p.h / 2, + r: Math.max(p.w, p.h) / 2, + class: "sim-board-button" + }) as SVGCircleElement + svg.title(this.element, "RESET"); + // hooking up events + pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { + pxsim.U.addClass(this.element, "pressed"); + pxsim.Runtime.postMessage({ + type: "simulator", + command: "restart" + }) + })); + this.element.addEventListener(pointerEvents.leave, ev => { + pxsim.U.removeClass(this.element, "pressed"); + }) + this.element.addEventListener(pointerEvents.up, ev => { + pxsim.U.removeClass(this.element, "pressed"); + }) + } + } + + class BoardLed { + private colorOff = "#aaa" + private backElement: SVGElement; + private ledElement: SVGElement; + element: SVGElement; + + constructor(x: number, y: number, private colorOn: string, private pin: Pin, w: number, h: number) { + this.backElement = svg.elt("rect", { x, y, width: w, height: h, fill: this.colorOff }); + this.ledElement = svg.elt("rect", { x, y, width: w, height: h, fill: this.colorOn, opacity: 0 }); + svg.filter(this.ledElement, `url(#neopixelglow)`); + this.element = svg.elt("g", { class: "sim-led" }); + this.element.appendChild(this.backElement); + this.element.appendChild(this.ledElement); + } + + updateTheme(colorOff: string, colorOn: string) { + if (colorOff) { + this.colorOff = colorOff; + } + if (colorOn) { + this.colorOn = colorOn; + } + } + + updateState() { + const opacity = this.pin.mode & PinFlags.Digital ? (this.pin.value > 0 ? 1 : 0) + : 0.1 + Math.max(0, Math.min(1023, this.pin.value)) / 1023 * 0.8; + this.ledElement.setAttribute("opacity", opacity.toString()) + } + } + + interface CandleDefinition { + id: string; + x: number; + y: number; + r: number; + color: string; + } + + interface BoardVisualDefinition extends BoardImageDefinition { + candles?: CandleDefinition[]; + } + + class BoardNeopixel { + name: string; + element: SVGGElement; + private candles: Array<{ + element: SVGCircleElement; + defaultColor: string; + index: number; // 0-7 for the 8 candles + }> = []; + private pixelColors: {[index: number]: [number, number, number]} = {}; + private pixelCount: number = 0; + private state: any; // Using any to avoid TypeScript issues with neopixelState + + constructor(name: string, x: number, y: number, r: number) { + this.name = name; + this.element = svg.elt("g") as SVGGElement; + this.element.setAttribute("class", "neopixel"); + + // Create a circle for the neopixel (hidden by default) + const circle = svg.elt("circle", { + cx: x, + cy: y, + r: r, + fill: "#000000" + }) as SVGCircleElement; + circle.style.display = "none"; + this.element.appendChild(circle); + + // Create candles if defined in board definition + const board = (window as any).board as any; + if (board?.boardDefinition?.visual) { + const visualDef = board.boardDefinition.visual; + if (typeof visualDef === 'object' && 'candles' in visualDef && Array.isArray(visualDef.candles)) { + this.createCandles(visualDef.candles); + } + } + + // Initialize neopixel state + this.initNeoPixelState(); + } + + private initNeoPixelState() { + // Try to get the neopixel state + this.state = (window as any).board?.neopixelState?.(this.name); + + if (this.state) { + // Override the update method to ensure our visualization updates + const originalUpdate = this.state.update; + this.state.update = () => { + if (originalUpdate) originalUpdate.call(this.state); + this.updateFromState(); + }; + + // Initialize with current state + this.updateFromState(); + } + } + + private createCandles(candleDefs: CandleDefinition[]) { + // Separate shamash from regular candles + const regularCandles = candleDefs.filter(c => !c.id.includes('shamash')); + const shamash = candleDefs.find(c => c.id.includes('shamash')); + + // Sort regular candles by x-coordinate (left to right) + const sortedCandles = [...regularCandles].sort((a, b) => a.x - b.x); + + // Create regular candles (indices 0-6) + sortedCandles.forEach((def, i) => { + if (i >= 7) return; // Only take first 7 candles + + const candle = svg.elt("circle", { + cx: def.x, + cy: def.y, + r: def.r, + fill: def.color, + class: `candle ${def.id}` + }) as SVGCircleElement; + + svg.filter(candle, `url(#neopixelglow)`); + + this.candles.push({ + element: candle, + defaultColor: def.color, + index: i + }); + + this.pixelColors[i] = [0, 0, 0]; + this.pixelCount = Math.max(this.pixelCount, i + 1); + this.element.appendChild(candle); + }); + + // Add shamash as index 7 if it exists + if (shamash) { + const candle = svg.elt("circle", { + cx: shamash.x, + cy: shamash.y, + r: shamash.r, + fill: shamash.color, + class: `candle ${shamash.id} shamash` + }) as SVGCircleElement; + + svg.filter(candle, `url(#neopixelglow)`); + + this.candles.push({ + element: candle, + defaultColor: shamash.color, + index: 7 + }); + + this.pixelColors[7] = [0, 0, 0]; + this.pixelCount = Math.max(this.pixelCount, 8); + this.element.appendChild(candle); + } + } + + /** + * Dim a hex color by a specific factor + * @param color Hex color string (e.g., "#FF0000") + * @param factor Dim factor (0-1, where 1 is original color, 0 is black) + */ + private dimColor(color: string, factor: number): string { + // Remove the '#' if present + const hex = color.startsWith('#') ? color.slice(1) : color; + + // Parse the hex color into RGB components + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + + // Dim each component by the factor + const dimR = Math.round(r * factor); + const dimG = Math.round(g * factor); + const dimB = Math.round(b * factor); + + // Convert back to hex + return this.rgbToHex(dimR, dimG, dimB); + } + + /** + * Convert RGB values (0-255) to CSS hex color + */ + private rgbToHex(r: number, g: number, b: number): string { + return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); + } + + /** + * Set the color of a specific pixel (candle) + * @param pixelIndex Index of the pixel (0-7 for the 8 candles) + * @param rgb RGB color as [r, g, b] (0-255) + */ + setPixelColor(pixelIndex: number, r: number, g: number, b: number) { + if (pixelIndex < 0 || pixelIndex >= this.pixelCount) return; + + // Store the color and update immediately + this.pixelColors[pixelIndex] = [r, g, b]; + this.updateCandle(pixelIndex); + } + + /** + * Set all pixels to the same color + * @param rgb RGB color as [r, g, b] (0-255) + */ + setAll(r: number, g: number, b: number) { + // Update all pixels at once + for (let i = 0; i < this.pixelCount; i++) { + this.pixelColors[i] = [r, g, b]; + this.updateCandle(i); + } + } + + /** + * Update the visual representation of a candle based on its pixel color + * @param pixelIndex Index of the pixel/candle to update + */ + private updateCandle(pixelIndex: number) { + const candle = this.candles.find(c => c.index === pixelIndex); + if (!candle) return; + + const [r, g, b] = this.pixelColors[pixelIndex] || [0, 0, 0]; + const isShamash = candle.element.classList.contains('shamash'); + + if (isShamash) { + // Special handling for shamash - keep yellow tint + if (r === 0 && g === 0 && b === 0) { + // Dim when off + const dimmedColor = this.dimColor(candle.defaultColor, 0.3); + svg.fill(candle.element, dimmedColor); + } else { + // Mix with yellow to maintain the shamash appearance + const [or, og, ob] = this.hexToRgb(candle.defaultColor); + const mixed = this.mixColors([r, g, b], [or, og, ob], 0.5); + svg.fill(candle.element, this.rgbToHex(...mixed)); + } + return; + } + + // Regular candle behavior + if (r === 0 && g === 0 && b === 0) { + // Dim when off + const dimmedColor = this.dimColor(candle.defaultColor, 0.1); + svg.fill(candle.element, dimmedColor); + } else { + // Set to the specified color + const color = this.rgbToHex(r, g, b); + svg.fill(candle.element, color); + + // Add glow effect based on brightness + const brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 2.55; + const glowIntensity = Math.max(0.3, brightness / 100); + const glowColor = this.rgbToHex( + Math.min(255, r + 100 * glowIntensity), + Math.min(255, g + 100 * glowIntensity), + Math.min(255, b + 100 * glowIntensity) + ); + candle.element.style.filter = `drop-shadow(0 0 ${5 * glowIntensity}px ${glowColor})`; + } + } + + /** + * Update candle colors from the neopixel state + */ + private updateFromState() { + if (!this.state) return; + + try { + // Use requestAnimationFrame to batch updates + requestAnimationFrame(() => { + // Update each pixel + for (let i = 0; i < this.pixelCount; i++) { + const colors = this.state.pixelColor(i); + if (colors && colors.length >= 3) { + this.setPixelColor(i, colors[0], colors[1], colors[2]); + } + } + }); + } catch (e) { + console.error('Error updating neopixel state:', e); + } + } + + /** + * Helper to convert hex color to RGB + */ + private hexToRgb(hex: string): [number, number, number] { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return [r, g, b]; + } + + /** + * Mix two colors with a given ratio (0-1) + */ + private mixColors(rgb1: [number, number, number], rgb2: [number, number, number], ratio: number): [number, number, number] { + return [ + Math.round(rgb1[0] * (1 - ratio) + rgb2[0] * ratio), + Math.round(rgb1[1] * (1 - ratio) + rgb2[1] * ratio), + Math.round(rgb1[2] * (1 - ratio) + rgb2[2] * ratio) + ]; + } + + // Keep the old setColor for backward compatibility + // This handles both setColor([r,g,b]) and setColor(r,g,b) for compatibility + setColor(r: number | number[], g?: number, b?: number) { + let red: number, green: number, blue: number; + + if (Array.isArray(r)) { + // Called with array: [r,g,b] + [red, green, blue] = r; + } else if (g !== undefined && b !== undefined) { + // Called with individual components + red = r as number; + green = g; + blue = b; + } else { + // Invalid arguments, default to black + red = green = blue = 0; + } + + this.setAll(red, green, blue); + + // Update the neopixel state if available + if (this.state) { + const stride = (this.state as any).stride || 3; + for (let i = 0; i < this.pixelCount; i++) { + (this.state as any).setBufferRGB(i * stride, red, green, blue); + } + // Trigger update if available + if (typeof (this.state as any).update === 'function') { + (this.state as any).update(); + } + } + } + } + + class BoardButton { + element: SVGElement; + def: ButtonDefinition; + button: CommonButton; + constructor(def: ButtonDefinition) { + this.def = def; + def.w = def.w || 15; + def.h = def.h || 15; + this.element = svg.elt("circle", { + cx: def.x + def.w / 2, + cy: def.y + def.h / 2, + r: Math.max(def.w, def.h) / 2, + class: "sim-board-button" + }) as SVGCircleElement + svg.title(this.element, def.label); + // resolve button + this.button = def.index !== undefined + ? pxsim.pxtcore.getButton(def.index) + : pxsim.pxtcore.getButtonByPin(pxsim.pinIds[def.label]); + // hooking up events + pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { + this.button.setPressed(true); + pxsim.U.addClass(this.element, "pressed"); + })); + this.element.addEventListener(pointerEvents.leave, ev => { + pxsim.U.removeClass(this.element, "pressed"); + this.button.setPressed(false); + }) + this.element.addEventListener(pointerEvents.up, ev => { + pxsim.U.removeClass(this.element, "pressed"); + this.button.setPressed(false); + }) + } + } + + class BoardTouchButton { + element: SVGElement; + def: TouchPadDefinition; + button: TouchButton; + constructor(def: TouchPadDefinition, pinId: number) { + this.def = def; + def.w = def.w || 15; + def.h = def.h || 15; + this.element = svg.elt("circle", { + cx: def.x + def.w / 2, + cy: def.y + def.h / 2, + r: Math.max(def.w, def.h) / 2, + class: "sim-board-button" + }) as SVGCircleElement + svg.title(this.element, def.label); + // resolve button + this.button = pxsim.pxtcore.getTouchButton(pinId); + // hooking up events + pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { + this.button.setPressed(true); + pxsim.U.addClass(this.element, "pressed"); + })); + this.element.addEventListener(pointerEvents.leave, ev => { + pxsim.U.removeClass(this.element, "pressed"); + this.button.setPressed(false); + }) + this.element.addEventListener(pointerEvents.up, ev => { + pxsim.U.removeClass(this.element, "pressed"); + this.button.setPressed(false); + }) + } + } +} \ No newline at end of file diff --git a/sim/visuals/led-candles.ts b/sim/visuals/led-candles.ts new file mode 100644 index 00000000..b58eaf98 --- /dev/null +++ b/sim/visuals/led-candles.ts @@ -0,0 +1,135 @@ +/// + +namespace pxsim.visuals { + export function mkLedMatrixSvg(xy: Coord, rows: number, cols: number): + { el: SVGGElement, y: number, x: number, w: number, h: number, leds: SVGElement[], ledsOuter: SVGElement[], background: SVGElement } { + let result: { el: SVGGElement, y: number, x: number, w: number, h: number, leds: SVGElement[], ledsOuter: SVGElement[], background: SVGElement } + = { el: null, y: 0, x: 0, w: 0, h: 0, leds: [], ledsOuter: [], background: null }; + result.el = svg.elt("g"); + let width = cols * PIN_DIST; + let height = rows * PIN_DIST; + let ledRad = Math.round(PIN_DIST * .35); + let spacing = PIN_DIST; + let padding = (spacing - 2 * ledRad) / 2.0; + let [x, y] = xy; + let left = x - (ledRad + padding); + let top = y - (ledRad + padding); + result.x = left; + result.y = top; + result.w = width; + result.h = height; + result.background = svg.child(result.el, "rect", { class: "sim-display", x: left, y: top, width: width, height: height }) + + // ledsOuter + result.leds = []; + result.ledsOuter = []; + let hoverRad = ledRad * 1.2; + for (let i = 0; i < rows; ++i) { + let y = top + ledRad + i * spacing + padding; + for (let j = 0; j < cols; ++j) { + let x = left + ledRad + j * spacing + padding; + result.ledsOuter.push(svg.child(result.el, "circle", { class: "sim-led-back", cx: x, cy: y, r: ledRad })); + result.leds.push(svg.child(result.el, "circle", { class: "sim-led", cx: x, cy: y, r: hoverRad, title: `(${j},${i})` })); + } + } + + //default theme + svg.fill(result.background, defaultLedMatrixTheme.background); + svg.fills(result.leds, defaultLedMatrixTheme.ledOn); + svg.fills(result.ledsOuter, defaultLedMatrixTheme.ledOff); + + //turn off LEDs + result.leds.forEach(l => (l).style.opacity = 0 + ""); + + return result; + } + + export interface ILedMatrixTheme { + background?: string; + ledOn?: string; + ledOff?: string; + } + export var defaultLedMatrixTheme: ILedMatrixTheme = { + background: "#000", + ledOn: "#ff5f5f", + ledOff: "#DDD", + }; + + export const LED_MATRIX_STYLE = ` + .sim-led-back:hover { + stroke:#a0a0a0; + stroke-width:3px; + } + .sim-led:hover { + stroke:#ff7f7f; + stroke-width:3px; + } + ` + + export class LedMatrixView implements IBoardPart { + private background: SVGElement; + private ledsOuter: SVGElement[]; + private leds: SVGElement[]; + private state: LedMatrixState; + private bus: EventBus; + public element: SVGElement; + public defs: SVGElement[]; + private theme: ILedMatrixTheme; + + private DRAW_SIZE = 8; + private ACTIVE_SIZE = 5; + + public style = LED_MATRIX_STYLE; + + public init(bus: EventBus, state: LedMatrixState) { + this.bus = bus; + this.state = state; + this.theme = defaultLedMatrixTheme; + this.defs = []; + this.element = this.buildDom(); + } + + public moveToCoord(xy: Coord) { + translateEl(this.element, xy); + } + + public updateTheme() { + svg.fill(this.background, this.theme.background); + svg.fills(this.leds, this.theme.ledOn); + svg.fills(this.ledsOuter, this.theme.ledOff); + } + + public updateState() { + if (this.state.disabled) { + this.leds.forEach((led, i) => { + let sel = (led) + sel.style.opacity = 0 + ""; + }); + return; + } + + const bw = this.state.displayMode == pxsim.DisplayMode.bw + const img = this.state.image; + this.leds.forEach((led, i) => { + let sel = (led) + let dx = i % this.DRAW_SIZE; + let dy = (i - dx) / this.DRAW_SIZE; + if (dx < this.ACTIVE_SIZE && dy < this.ACTIVE_SIZE) { + let j = dx + dy * this.ACTIVE_SIZE; + sel.style.opacity = ((bw ? img.data[j] > 0 ? 255 : 0 : img.data[j]) / 255.0) + ""; + } else { + sel.style.opacity = 0 + ""; + } + }) + } + + public buildDom() { + let res = mkLedMatrixSvg([0, 0], this.DRAW_SIZE, this.DRAW_SIZE); + let display = res.el; + this.background = res.background; + this.leds = res.leds; + this.ledsOuter = res.ledsOuter; + return display; + } + } +} \ No newline at end of file From d5fe31f0e2d8ce11b22a84e2c25214b0643b7772 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:18:44 -0700 Subject: [PATCH 09/19] candle draft --- sim/visuals/board.ts | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 24bd9afd..e51a6925 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -102,9 +102,93 @@ namespace pxsim.visuals { disableTilt?: boolean; } + export interface ICandleTheme { + candleOn?: string; + candleOff?: string; + glowColor?: string; + } + + export const defaultCandleTheme: ICandleTheme = { + candleOn: "#ff8c1a", // Bright orange for lit candles + candleOff: "#4d4d4d", // Dark gray for unlit candles + glowColor: "#ffcc00" // Yellow glow for candles + }; + + const CANDLE_STYLE = ` +.sim-candle { + transition: fill 0.3s ease, filter 0.3s ease; +} +.sim-candle.glow { + filter: url(#candle-glow); +} + `; + + function createGlowEffects(defs: SVGElement) { + // Create glow effect for candles + const candleGlow = svg.elt("filter", { id: "candle-glow", x: "-50%", y: "-50%", width: "200%", height: "200%" }); + candleGlow.innerHTML = ` + + + `; + defs.appendChild(candleGlow); + } + + class CandleView { + public element: SVGGElement; + private candles: {element: SVGCircleElement, defaultColor: string}[] = []; + private theme: ICandleTheme; + + constructor() { + this.theme = {...defaultCandleTheme}; + this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; + this.createCandles(); + } + + private createCandles() { + const board = (window as any).board as pxsim.DalBoard; + if (!board?.boardDefinition?.visual?.candles) return; + + board.boardDefinition.visual.candles.forEach((candleDef: any) => { + const candle = svg.elt("circle", { + cx: candleDef.x, + cy: candleDef.y, + r: candleDef.r, + class: "sim-candle", + fill: this.theme.candleOff + }) as SVGCircleElement; + + // Add glow effect + svg.filter(candle, "url(#candle-glow)"); + + this.candles.push({ + element: candle, + defaultColor: candleDef.color || this.theme.candleOn + }); + + this.element.appendChild(candle); + }); + } + + public updateTheme(theme?: ICandleTheme) { + if (theme) { + this.theme = {...defaultCandleTheme, ...theme}; + } + this.updateCandles(); + } + + private updateCandles() { + this.candles.forEach(candle => { + // In Phase 1, we'll just use the default colors + // We'll add NeoPixel integration in Phase 2 + svg.fill(candle.element, candle.defaultColor); + }); + } + } + export class MetroBoardSvg extends GenericBoardSvg { public board: pxsim.DalBoard; + private candleView: CandleView; private onBoardLeds: BoardLed[]; private onBoardNeopixels: BoardNeopixel[]; private onBoardReset: BoardResetButton; @@ -122,6 +206,30 @@ namespace pxsim.visuals { this.onBoardTouchPads = []; this.onBoardButtons = []; + this.onBoardNeopixels = []; + for (const l of props.visualDef.leds || []) { + if (l.color == "neopixel") { + const onBoardNeopixel = new BoardNeopixel(l.label, l.x, l.y, l.w || 0); + this.onBoardNeopixels.push(onBoardNeopixel); + el.appendChild(onBoardNeopixel.element); + } + } + + // Add this right after the NeoPixel initialization + if (props.visualDef.candles) { + // Add the glow effects to the defs + createGlowEffects(this.defs); + + // Create and add the candle view + this.candleView = new CandleView(); + el.appendChild(this.candleView.element); + + // Add the candle styles + const style = document.createElement("style"); + style.textContent = CANDLE_STYLE; + el.appendChild(style); + } + // neopixels/leds for (const l of props.visualDef.leds || []) { if (l.color == "neopixel") { From e3701a93097f2136816035505be1a63101409c87 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:24:12 -0700 Subject: [PATCH 10/19] reverted some changes --- .../BreadboardViewGraphic_Template.svg | 289 -------- libs/atisa-menorah/board.svg.backup | 682 ------------------ sim/visuals/board.ts | 204 +----- 3 files changed, 11 insertions(+), 1164 deletions(-) delete mode 100644 libs/atisa-menorah/BreadboardViewGraphic_Template.svg delete mode 100644 libs/atisa-menorah/board.svg.backup diff --git a/libs/atisa-menorah/BreadboardViewGraphic_Template.svg b/libs/atisa-menorah/BreadboardViewGraphic_Template.svg deleted file mode 100644 index f84d0ec2..00000000 --- a/libs/atisa-menorah/BreadboardViewGraphic_Template.svg +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - - - - - 0.1 inch - - - - 0.03 inch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Atisa - Menorah - - diff --git a/libs/atisa-menorah/board.svg.backup b/libs/atisa-menorah/board.svg.backup deleted file mode 100644 index 4dd6f89e..00000000 --- a/libs/atisa-menorah/board.svg.backup +++ /dev/null @@ -1,682 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index e51a6925..8dc07b61 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -102,93 +102,9 @@ namespace pxsim.visuals { disableTilt?: boolean; } - export interface ICandleTheme { - candleOn?: string; - candleOff?: string; - glowColor?: string; - } - - export const defaultCandleTheme: ICandleTheme = { - candleOn: "#ff8c1a", // Bright orange for lit candles - candleOff: "#4d4d4d", // Dark gray for unlit candles - glowColor: "#ffcc00" // Yellow glow for candles - }; - - const CANDLE_STYLE = ` -.sim-candle { - transition: fill 0.3s ease, filter 0.3s ease; -} -.sim-candle.glow { - filter: url(#candle-glow); -} - `; - - function createGlowEffects(defs: SVGElement) { - // Create glow effect for candles - const candleGlow = svg.elt("filter", { id: "candle-glow", x: "-50%", y: "-50%", width: "200%", height: "200%" }); - candleGlow.innerHTML = ` - - - `; - defs.appendChild(candleGlow); - } - - class CandleView { - public element: SVGGElement; - private candles: {element: SVGCircleElement, defaultColor: string}[] = []; - private theme: ICandleTheme; - - constructor() { - this.theme = {...defaultCandleTheme}; - this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; - this.createCandles(); - } - - private createCandles() { - const board = (window as any).board as pxsim.DalBoard; - if (!board?.boardDefinition?.visual?.candles) return; - - board.boardDefinition.visual.candles.forEach((candleDef: any) => { - const candle = svg.elt("circle", { - cx: candleDef.x, - cy: candleDef.y, - r: candleDef.r, - class: "sim-candle", - fill: this.theme.candleOff - }) as SVGCircleElement; - - // Add glow effect - svg.filter(candle, "url(#candle-glow)"); - - this.candles.push({ - element: candle, - defaultColor: candleDef.color || this.theme.candleOn - }); - - this.element.appendChild(candle); - }); - } - - public updateTheme(theme?: ICandleTheme) { - if (theme) { - this.theme = {...defaultCandleTheme, ...theme}; - } - this.updateCandles(); - } - - private updateCandles() { - this.candles.forEach(candle => { - // In Phase 1, we'll just use the default colors - // We'll add NeoPixel integration in Phase 2 - svg.fill(candle.element, candle.defaultColor); - }); - } - } - export class MetroBoardSvg extends GenericBoardSvg { public board: pxsim.DalBoard; - private candleView: CandleView; private onBoardLeds: BoardLed[]; private onBoardNeopixels: BoardNeopixel[]; private onBoardReset: BoardResetButton; @@ -206,30 +122,6 @@ namespace pxsim.visuals { this.onBoardTouchPads = []; this.onBoardButtons = []; - this.onBoardNeopixels = []; - for (const l of props.visualDef.leds || []) { - if (l.color == "neopixel") { - const onBoardNeopixel = new BoardNeopixel(l.label, l.x, l.y, l.w || 0); - this.onBoardNeopixels.push(onBoardNeopixel); - el.appendChild(onBoardNeopixel.element); - } - } - - // Add this right after the NeoPixel initialization - if (props.visualDef.candles) { - // Add the glow effects to the defs - createGlowEffects(this.defs); - - // Create and add the candle view - this.candleView = new CandleView(); - el.appendChild(this.candleView.element); - - // Add the candle styles - const style = document.createElement("style"); - style.textContent = CANDLE_STYLE; - el.appendChild(style); - } - // neopixels/leds for (const l of props.visualDef.leds || []) { if (l.color == "neopixel") { @@ -380,101 +272,27 @@ namespace pxsim.visuals { } } - interface CandleDefinition { - id: string; - x: number; - y: number; - r: number; - color: string; - } - - interface BoardVisualDefinition extends BoardImageDefinition { - candles?: CandleDefinition[]; - } - class BoardNeopixel { name: string; - element: SVGGElement; - private candles: {element: SVGCircleElement, defaultColor: string}[] = []; + element: SVGCircleElement; constructor(name: string, x: number, y: number, r: number) { this.name = name; - this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; - - // Create the main neopixel element (kept for backward compatibility) - const mainPixel = svg.elt("circle", { - cx: x + r / 2, - cy: y + r / 2, - r: 10, - style: "display: none" // Hide the original neopixel - }) as SVGCircleElement; - this.element.appendChild(mainPixel); - - // Create candle elements if we're on the Atisa Menorah board - const board = (window as any).board as pxsim.DalBoard; - if (board?.boardDefinition?.visual) { - const visualDef = board.boardDefinition.visual as BoardVisualDefinition; - if (visualDef.candles) { - this.createCandles(visualDef.candles); - } - } - } - - private createCandles(candleDefs: CandleDefinition[]) { - for (const candleDef of candleDefs) { - const candle = svg.elt("circle", { - cx: candleDef.x, - cy: candleDef.y, - r: candleDef.r, - fill: candleDef.color, - class: `candle ${candleDef.id}` - }) as SVGCircleElement; - - // Add glow effect to candles - svg.filter(candle, `url(#neopixelglow)`); - - this.candles.push({ - element: candle, - defaultColor: candleDef.color - }); - - this.element.appendChild(candle); - } + this.element = svg.elt("circle", { cx: x + r / 2, cy: y + r / 2, r: 10 }) as SVGCircleElement + svg.title(this.element, name); } setColor(rgb: [number, number, number]) { - if (!this.candles.length) { - // Fallback to original behavior if no candles - const hsl = visuals.rgbToHsl(rgb); - const [h, s, l] = hsl; - const lx = Math.max(l * 1.3, 85); - - this.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)`; - this.element.style.strokeWidth = "1.5"; - svg.fill(this.element, `hsl(${h}, ${s}%, ${lx}%)`); - svg.filter(this.element, `url(#neopixelglow)`); - return; - } - - // For the Menorah, we'll set all candles to the same color for now - // In the future, we could map different neopixel indices to different candles const hsl = visuals.rgbToHsl(rgb); - const [h, s, l] = hsl; + let [h, s, l] = hsl; const lx = Math.max(l * 1.3, 85); - - for (const candle of this.candles) { - // For the shamash, we might want to keep its original color - const isShamash = (candle.element.getAttribute('class') || '').includes('shamash'); - if (isShamash) { - // Optionally keep shamash color or apply a different effect - // For now, we'll keep its original color - continue; - } - - candle.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)`; - candle.element.style.strokeWidth = "1.5"; - svg.fill(candle.element, `hsl(${h}, ${s}%, ${lx}%)`); - } + + // at least 10% luminosity + l = l * 90 / 100 + 10; + this.element.style.stroke = `hsl(${h}, ${s}%, ${Math.min(l * 3, 75)}%)` + this.element.style.strokeWidth = "1.5"; + svg.fill(this.element, `hsl(${h}, ${s}%, ${lx}%)`); + svg.filter(this.element, `url(#neopixelglow)`); } } From b8b702f109d338a3dd9f481961355158ad63a00a Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Tue, 15 Jul 2025 18:40:20 -0700 Subject: [PATCH 11/19] draft led-candles -> pxsim.visuals --- libs/atisa-menorah/board.svg | 16 +-- libs/atisa-menorah/boardhd.svg | 43 ++++++-- sim/visuals/led-candles.ts | 194 ++++++++++++++------------------- 3 files changed, 122 insertions(+), 131 deletions(-) diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index e809cc99..2d073a4f 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -1,14 +1,14 @@ - - - - - - - - + + + + + + + + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg index fdc88d3d..48bc2d9d 100644 --- a/libs/atisa-menorah/boardhd.svg +++ b/libs/atisa-menorah/boardhd.svg @@ -21,43 +21,68 @@ transform="matrix(6.5102698,0,0,6.5102698,-1648.4956,-2304.6356)"> + + + + + + + + + r="1.7528598" + class="sim-candle" + /> + namespace pxsim.visuals { - export function mkLedMatrixSvg(xy: Coord, rows: number, cols: number): - { el: SVGGElement, y: number, x: number, w: number, h: number, leds: SVGElement[], ledsOuter: SVGElement[], background: SVGElement } { - let result: { el: SVGGElement, y: number, x: number, w: number, h: number, leds: SVGElement[], ledsOuter: SVGElement[], background: SVGElement } - = { el: null, y: 0, x: 0, w: 0, h: 0, leds: [], ledsOuter: [], background: null }; - result.el = svg.elt("g"); - let width = cols * PIN_DIST; - let height = rows * PIN_DIST; - let ledRad = Math.round(PIN_DIST * .35); - let spacing = PIN_DIST; - let padding = (spacing - 2 * ledRad) / 2.0; - let [x, y] = xy; - let left = x - (ledRad + padding); - let top = y - (ledRad + padding); - result.x = left; - result.y = top; - result.w = width; - result.h = height; - result.background = svg.child(result.el, "rect", { class: "sim-display", x: left, y: top, width: width, height: height }) - - // ledsOuter - result.leds = []; - result.ledsOuter = []; - let hoverRad = ledRad * 1.2; - for (let i = 0; i < rows; ++i) { - let y = top + ledRad + i * spacing + padding; - for (let j = 0; j < cols; ++j) { - let x = left + ledRad + j * spacing + padding; - result.ledsOuter.push(svg.child(result.el, "circle", { class: "sim-led-back", cx: x, cy: y, r: ledRad })); - result.leds.push(svg.child(result.el, "circle", { class: "sim-led", cx: x, cy: y, r: hoverRad, title: `(${j},${i})` })); - } - } - - //default theme - svg.fill(result.background, defaultLedMatrixTheme.background); - svg.fills(result.leds, defaultLedMatrixTheme.ledOn); - svg.fills(result.ledsOuter, defaultLedMatrixTheme.ledOff); - - //turn off LEDs - result.leds.forEach(l => (l).style.opacity = 0 + ""); - - return result; + export interface ICandleTheme { + candleOn?: string; + candleOff?: string; } - export interface ILedMatrixTheme { - background?: string; - ledOn?: string; - ledOff?: string; - } - export var defaultLedMatrixTheme: ILedMatrixTheme = { - background: "#000", - ledOn: "#ff5f5f", - ledOff: "#DDD", + export const defaultCandleTheme: ICandleTheme = { + candleOn: "#ff8c1a", // Bright orange for lit candles + candleOff: "#4d4d4d" // Dark gray for unlit candles }; - export const LED_MATRIX_STYLE = ` - .sim-led-back:hover { - stroke:#a0a0a0; - stroke-width:3px; - } - .sim-led:hover { - stroke:#ff7f7f; - stroke-width:3px; - } - ` - - export class LedMatrixView implements IBoardPart { - private background: SVGElement; - private ledsOuter: SVGElement[]; - private leds: SVGElement[]; - private state: LedMatrixState; - private bus: EventBus; - public element: SVGElement; - public defs: SVGElement[]; - private theme: ILedMatrixTheme; - - private DRAW_SIZE = 8; - private ACTIVE_SIZE = 5; - - public style = LED_MATRIX_STYLE; - - public init(bus: EventBus, state: LedMatrixState) { - this.bus = bus; - this.state = state; - this.theme = defaultLedMatrixTheme; - this.defs = []; - this.element = this.buildDom(); + export class CandleView { + public element: SVGGElement; + private candles: SVGCircleElement[] = []; + private theme: ICandleTheme; + private board: pxsim.DalBoard; + + constructor() { + this.theme = {...defaultCandleTheme}; + this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; + this.board = (window as any).board as pxsim.DalBoard; + this.createCandles(); } - public moveToCoord(xy: Coord) { - translateEl(this.element, xy); + private createCandles() { + // Create 7 candles (6 regular + 1 shamash, but we'll handle all the same for now) + for (let i = 0; i < 7; i++) { + const candle = svg.elt("circle", { + r: 15, + class: "sim-candle", + fill: this.theme.candleOff + }) as SVGCircleElement; + + // Position will be set by the parent component + this.candles.push(candle); + this.element.appendChild(candle); + } } - public updateTheme() { - svg.fill(this.background, this.theme.background); - svg.fills(this.leds, this.theme.ledOn); - svg.fills(this.ledsOuter, this.theme.ledOff); + private updateCandles() { + if (!this.candles.length) return; + + // Update all candles to their current theme state + this.candles.forEach(candle => { + // If we have a board and it's initialized, use the NeoPixel state + if (this.board) { + const index = this.candles.indexOf(candle); + const neopixel = this.board.neopixelState(index); + if (neopixel) { + const rgb = neopixel.pixelColor(0); + if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { + // If pixel has color, use it + svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); + return; + } + } + } + + // Otherwise use the theme's off color + svg.fill(candle, this.theme.candleOff); + }); } - public updateState() { - if (this.state.disabled) { - this.leds.forEach((led, i) => { - let sel = (led) - sel.style.opacity = 0 + ""; - }); - return; + public updateTheme(theme?: ICandleTheme) { + if (theme) { + this.theme = {...defaultCandleTheme, ...theme}; } + this.updateCandles(); + } - const bw = this.state.displayMode == pxsim.DisplayMode.bw - const img = this.state.image; - this.leds.forEach((led, i) => { - let sel = (led) - let dx = i % this.DRAW_SIZE; - let dy = (i - dx) / this.DRAW_SIZE; - if (dx < this.ACTIVE_SIZE && dy < this.ACTIVE_SIZE) { - let j = dx + dy * this.ACTIVE_SIZE; - sel.style.opacity = ((bw ? img.data[j] > 0 ? 255 : 0 : img.data[j]) / 255.0) + ""; - } else { - sel.style.opacity = 0 + ""; + public updateState() { + if (!this.board) return; + + // Update each candle based on NeoPixel state + this.candles.forEach((candle, index) => { + const neopixel = this.board.neopixelState(index); + if (neopixel) { + const rgb = neopixel.pixelColor(0); // Get first pixel in strip + if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { + // If the pixel has color, use it + svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); + } else { + // Otherwise use the theme's off color + svg.fill(candle, this.theme.candleOff); + } } - }) + }); } - public buildDom() { - let res = mkLedMatrixSvg([0, 0], this.DRAW_SIZE, this.DRAW_SIZE); - let display = res.el; - this.background = res.background; - this.leds = res.leds; - this.ledsOuter = res.ledsOuter; - return display; + public setPositions(positions: {x: number, y: number}[]) { + positions.forEach((pos, index) => { + if (index < this.candles.length) { + this.candles[index].setAttribute('cx', pos.x.toString()); + this.candles[index].setAttribute('cy', pos.y.toString()); + } + }); } } } \ No newline at end of file From 3bf55d9d62818140733cc1b46534117dc43bcf1a Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:56:36 -0700 Subject: [PATCH 12/19] moved candles to array instead of individual --- libs/atisa-menorah/board.json | 78 +++++++--------------------------- libs/atisa-menorah/board.svg | 14 +++--- libs/atisa-menorah/boardhd.svg | 71 +++++-------------------------- maker.code-workspace | 3 ++ pxtarget.json | 4 ++ sim/visuals/led-candles.ts | 21 ++++----- 6 files changed, 49 insertions(+), 142 deletions(-) diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 2e694810..94537d86 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -89,66 +89,26 @@ "label": "NEOPIXEL" }, { - "id": "candle0", - "x": 100, - "y": 200, + "id": "candles", + "x": 0, + "y": 0, "r": 15, "color": "neopixel", - "label": "NEOPIXEL0" - }, - { - "id": "candle1", - "x": 140, - "y": 180, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL1" - }, - { - "id": "candle2", - "x": 180, - "y": 160, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL2" - }, - { - "id": "candle3", - "x": 220, - "y": 140, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL3" - }, - { - "id": "candle4", - "x": 260, - "y": 160, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL4" - }, - { - "id": "candle5", - "x": 300, - "y": 180, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL5" - }, - { - "id": "candle6", - "x": 340, - "y": 200, - "r": 15, - "color": "neopixel", - "label": "NEOPIXEL6" + "label": "CANDLES", + "numPixels": 7 } ], + "candles": [ + {"x": 256.64, "y": 356.252, "index": 0}, + {"x": 265.278, "y": 356.252, "index": 1}, + {"x": 273.629, "y": 356.252, "index": 2}, + {"x": 284.647, "y": 356.252, "index": 3}, + {"x": 295.231, "y": 356.252, "index": 4}, + {"x": 304.249, "y": 356.252, "index": 5}, + {"x": 312.257, "y": 356.214, "index": 6} + ], "touchPads": [], - "buttons": [], - "candles": [ - ] + "buttons": [] }, "gpioPinMap": { "VBAT": "VBAT", @@ -177,13 +137,7 @@ "D0": "A2_D0_SDA", "SDA": "A2_D0_SDA", "LED": "LED", - "NEOPIXEL0": "NEOPIXEL0", - "NEOPIXEL1": "NEOPIXEL1", - "NEOPIXEL2": "NEOPIXEL2", - "NEOPIXEL3": "NEOPIXEL3", - "NEOPIXEL4": "NEOPIXEL4", - "NEOPIXEL5": "NEOPIXEL5", - "NEOPIXEL6": "NEOPIXEL6" + "NEOPIXEL": "NEOPIXEL" }, "groundPins": [ "GND" diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index 2d073a4f..9a25cb06 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -2,13 +2,13 @@ - - - - - - - + + + + + + + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg index 48bc2d9d..f19fd5e3 100644 --- a/libs/atisa-menorah/boardhd.svg +++ b/libs/atisa-menorah/boardhd.svg @@ -22,67 +22,16 @@ style="fill:#000000" d="m 269.52532,409.56275 v -0.94327 l 6.55342,-1.42601 c 3.60438,-0.7843 6.71827,-1.49391 6.91976,-1.57691 l 0.36634,-0.15091 v -5.20629 -5.20629 l -0.52916,-0.0806 c -0.29103,-0.0443 -1.20478,-0.15899 -2.03055,-0.25481 -9.24881,-1.07317 -17.85562,-7.18091 -22.26246,-15.79832 -1.88761,-3.69114 -3.18252,-8.7896 -3.18252,-12.53056 v -0.82051 h 1.38085 c 1.61106,0 1.4783,-0.19361 1.61879,2.36086 0.17111,3.11139 1.09398,6.38762 2.70595,9.60626 4.05977,8.10621 12.08699,13.61731 21.11867,14.49904 l 1.18043,0.11524 v -2.78894 c 0,-1.53392 -0.055,-2.78938 -0.12211,-2.7899 -0.75685,-0.006 -3.58674,-0.58133 -4.85749,-0.98764 -7.48728,-2.39397 -12.97131,-8.69333 -14.29555,-16.42091 -0.14465,-0.84412 -0.263,-1.99809 -0.263,-2.56438 v -1.02963 h 1.3574 1.35741 l 0.19402,1.78884 c 0.70789,6.52679 4.62339,12.02662 10.49273,14.73842 1.39281,0.64352 3.75832,1.31852 5.18721,1.48018 l 0.95707,0.10828 -0.0445,-2.89967 -0.0446,-2.89966 -1.13972,-0.28468 c -1.67401,-0.41811 -2.47848,-0.73505 -3.68935,-1.4535 -3.36209,-1.99482 -5.52395,-5.45148 -5.93265,-9.48587 l -0.11201,-1.10569 1.44783,0.0474 1.44782,0.0474 0.11383,1.03206 c 0.39031,3.53887 2.80915,6.6057 6.13631,7.78021 0.59217,0.20904 1.24152,0.38162 1.44301,0.38351 l 0.36634,0.003 v -4.64031 -4.64031 h 1.38395 1.38396 v 4.66112 4.66112 l 0.69197,-0.10393 c 1.28097,-0.1924 3.3291,-1.34245 4.53068,-2.54402 1.60108,-1.60108 2.75543,-4.16446 2.75543,-6.11878 v -0.56819 l 1.42465,0.047 1.42466,0.0471 -0.058,0.97691 c -0.30482,5.13055 -4.17167,9.63779 -9.34269,10.88994 l -1.42265,0.34449 -0.002,2.91244 -0.002,2.91244 0.93098,-0.10942 c 1.44863,-0.17026 3.35635,-0.70488 4.91856,-1.37839 5.84111,-2.51824 10.25626,-8.56048 10.68829,-14.62716 0.1537,-2.15843 0.0258,-2.00266 1.64403,-2.00266 h 1.40541 l -0.0993,1.50607 c -0.33985,5.15548 -2.58538,9.95166 -6.36991,13.60534 -3.41666,3.29853 -7.34201,5.14581 -12.3447,5.80946 l -0.77338,0.1026 v 2.77896 2.77897 l 1.18043,-0.11268 c 1.79882,-0.17172 4.23682,-0.7133 6.05496,-1.34505 10.10681,-3.51181 17.10038,-12.69999 17.81093,-23.40009 l 0.10905,-1.64217 h 1.38395 1.38396 l -0.0385,1.46536 c -0.114,4.34239 -1.64846,9.53426 -3.95289,13.37474 -3.08128,5.13512 -7.75275,9.3857 -12.97011,11.80153 -2.71718,1.25816 -6.40051,2.2736 -9.08941,2.50584 -0.62685,0.0541 -1.30458,0.13194 -1.50606,0.1729 l -0.36634,0.0745 v 5.27083 5.27083 l 0.36634,0.0855 c 0.20148,0.047 3.27874,0.7253 6.83835,1.50729 l 6.47202,1.42181 v 0.95263 0.95262 h -15.14207 -15.14207 z m -14.61629,-45.17491 c -0.2826,-0.38059 -0.77945,-1.02168 -1.10411,-1.42466 l -0.59029,-0.73268 3.45745,-0.044 c 1.9016,-0.0242 3.49229,-0.009 3.53486,0.0334 0.0426,0.0426 -0.28728,0.53862 -0.73302,1.10233 -0.44574,0.5637 -0.89685,1.18977 -1.00247,1.39126 -0.1769,0.33747 -0.30457,0.36634 -1.62032,0.36634 h -1.42829 z m 8.47059,0.0802 c -0.20112,-0.33512 -0.67114,-0.95745 -1.04449,-1.38296 -0.37335,-0.42551 -0.64082,-0.81165 -0.59437,-0.8581 0.0464,-0.0464 1.63757,-0.0646 3.53583,-0.0404 l 3.45138,0.044 -0.98451,1.30255 c -0.54148,0.71639 -0.98485,1.35749 -0.98528,1.42465 -4.2e-4,0.0672 -0.6785,0.12155 -1.50684,0.12086 l -1.50606,-0.001 z m 8.9236,0.30487 c -0.0904,-0.16882 -0.57662,-0.80991 -1.0806,-1.42465 l -0.91633,-1.11771 3.45956,-0.044 c 1.90276,-0.0242 3.49517,-0.008 3.53868,0.0351 0.0435,0.0435 -0.33355,0.61789 -0.83792,1.27639 -0.50436,0.6585 -0.91703,1.28379 -0.91703,1.38955 0,0.13429 -0.46479,0.19229 -1.54104,0.19229 -1.34314,0 -1.56214,-0.0394 -1.70532,-0.30696 z m 10.87929,-0.0594 c -0.10658,-0.20149 -0.49657,-0.73269 -0.86664,-1.18043 -1.28012,-1.54884 -1.56759,-1.38396 2.41299,-1.38396 1.93629,0 3.52052,0.0602 3.52052,0.13377 0,0.0736 -0.40297,0.63946 -0.8955,1.25753 -0.49252,0.61807 -0.8955,1.21728 -0.8955,1.33159 0,0.15393 -0.3997,0.20784 -1.54104,0.20784 -1.43215,0 -1.55473,-0.0259 -1.73483,-0.36634 z m 10.64421,0 c -0.0955,-0.20149 -0.54683,-0.80278 -1.00304,-1.33621 -0.45622,-0.53342 -0.82949,-1.02798 -0.82949,-1.09902 0,-0.071 1.57527,-0.12916 3.50059,-0.12916 1.92532,0 3.50059,0.0273 3.50059,0.0607 0,0.0334 -0.3751,0.52792 -0.83355,1.09902 -0.45845,0.5711 -0.90982,1.20322 -1.00304,1.40471 -0.15777,0.34099 -0.27291,0.36634 -1.664,0.36634 -1.38988,0 -1.50665,-0.0256 -1.66806,-0.36634 z m 8.65867,-0.0814 c -0.16073,-0.24627 -0.65755,-0.88736 -1.10405,-1.42466 l -0.81181,-0.97691 3.47001,-0.044 c 1.90851,-0.0242 3.50847,-0.006 3.55547,0.0414 0.047,0.047 -0.14573,0.35988 -0.4283,0.69529 -0.28256,0.3354 -0.74705,0.95785 -1.0322,1.38321 l -0.51845,0.77339 h -1.41921 c -1.36885,0 -1.42959,-0.0159 -1.71146,-0.44775 z m 8.27425,-0.16408 c -0.20111,-0.33512 -0.67113,-0.95745 -1.04448,-1.38296 -0.37336,-0.42551 -0.64082,-0.81165 -0.59437,-0.8581 0.0464,-0.0464 1.64125,-0.0646 3.54401,-0.0404 l 3.45956,0.044 -0.76285,0.97691 c -0.41957,0.5373 -0.86851,1.17839 -0.99765,1.42466 -0.23035,0.43928 -0.26318,0.44772 -1.73667,0.44649 l -1.50189,-10e-4 z m -55.51163,-3.09228 c -0.056,-0.15672 -0.48178,-0.76118 -0.94606,-1.34325 -0.46428,-0.58207 -0.89668,-1.1499 -0.96089,-1.26184 -0.0919,-0.16013 0.63156,-0.20352 3.39344,-0.20352 1.9306,0 3.50926,0.055 3.50813,0.12211 -0.001,0.0672 -0.39851,0.61461 -0.88307,1.21655 -0.48455,0.60194 -0.92817,1.24303 -0.98582,1.42465 -0.095,0.2994 -0.24104,0.33023 -1.56431,0.33023 -1.24262,0 -1.47464,-0.0423 -1.56142,-0.28493 z m 8.35086,-0.16282 c -0.12989,-0.24626 -0.60802,-0.88419 -1.06249,-1.41761 -0.45448,-0.53342 -0.82633,-1.02798 -0.82633,-1.09902 0,-0.071 1.57527,-0.12916 3.50059,-0.12916 1.92532,0 3.50059,0.0232 3.50059,0.0516 0,0.0284 -0.43926,0.63284 -0.97614,1.34325 -0.53687,0.71041 -0.97648,1.38324 -0.97691,1.49518 -5.6e-4,0.14764 -0.40196,0.20352 -1.46195,0.20352 -1.42821,0 -1.46651,-0.0101 -1.69736,-0.44775 z m 8.74016,0.0814 c -0.0931,-0.20149 -0.58111,-0.86696 -1.08446,-1.47884 -0.50334,-0.61187 -0.91516,-1.14306 -0.91516,-1.18043 0,-0.0374 1.57526,-0.0679 3.50058,-0.0679 1.92532,0 3.50059,0.0613 3.50059,0.13613 0,0.0749 -0.37329,0.60127 -0.82954,1.16976 -0.45625,0.56849 -0.89404,1.20328 -0.97288,1.41064 -0.13497,0.355 -0.22759,0.37701 -1.5866,0.37701 -1.338,0 -1.4556,-0.0267 -1.61253,-0.36634 z m 10.94524,0.0433 c -0.0564,-0.17766 -0.53757,-0.84371 -1.06929,-1.48012 -0.53173,-0.63642 -0.96677,-1.18711 -0.96677,-1.22376 0,-0.0367 1.57526,-0.0667 3.50058,-0.0667 1.98967,0 3.50059,0.0638 3.50059,0.14789 0,0.0813 -0.31855,0.53927 -0.70789,1.01761 -0.38934,0.47835 -0.83083,1.10784 -0.98109,1.39888 l -0.2732,0.52916 h -1.45021 c -1.30328,0 -1.46059,-0.0327 -1.55272,-0.32301 z m 10.64457,-0.0433 c -0.10639,-0.20149 -0.58521,-0.8402 -1.06404,-1.41935 -0.47883,-0.57916 -0.87061,-1.11036 -0.87061,-1.18043 0,-0.0701 1.57527,-0.12742 3.50059,-0.12742 1.92532,0 3.50059,0.0269 3.50059,0.0599 0,0.0329 -0.43961,0.62877 -0.97691,1.32405 -0.5373,0.69528 -0.97691,1.36437 -0.97691,1.48687 0,0.17185 -0.33337,0.22272 -1.45963,0.22272 -1.34784,0 -1.47445,-0.0281 -1.65308,-0.36634 z m 8.52299,-0.24548 c -0.20336,-0.33512 -0.71069,-1.01229 -1.12739,-1.50481 l -0.75764,-0.8955 3.47138,-0.044 c 1.90926,-0.0242 3.50565,-0.01 3.54754,0.0322 0.0419,0.0419 -0.37181,0.67066 -0.91933,1.39728 -0.54752,0.72661 -0.99549,1.38987 -0.99549,1.47391 0,0.084 -0.64109,0.15223 -1.42466,0.15154 l -1.42465,-10e-4 z m 8.29945,-0.16157 c -0.27725,-0.42536 -0.77517,-1.08626 -1.10647,-1.46867 -0.3313,-0.38241 -0.56574,-0.73193 -0.52097,-0.7767 0.0448,-0.0448 1.64045,-0.0616 3.54595,-0.0374 l 3.46456,0.044 -0.58916,0.73268 c -0.32404,0.40297 -0.79167,1.07965 -1.03917,1.50372 l -0.44999,0.77104 -1.40032,0.002 -1.40032,0.002 z" id="path840" /> - - - - - - - - - + + + + + + + + + + { - const neopixel = this.board.neopixelState(index); - if (neopixel) { - const rgb = neopixel.pixelColor(0); // Get first pixel in strip - if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { - // If the pixel has color, use it - svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); - } else { - // Otherwise use the theme's off color - svg.fill(candle, this.theme.candleOff); - } + const rgb = neopixel.pixelColor(index); // Get color for this candle's position + if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { + svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); + } else { + svg.fill(candle, this.theme.candleOff); } }); } From a2810f89a79e924830fa96a79d1990c7766d1107 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:58:43 -0700 Subject: [PATCH 13/19] replicated ledmatrix format --- libs/atisa-menorah/board.json | 16 +- libs/atisa-menorah/lantern.ts | 80 ++++ libs/atisa-menorah/pxt.json | 23 +- pxtarget.json | 1 - sim/state/ledcandles.ts | 107 +++++ sim/visuals/board-windsurf.ts.old | 419 ------------------ sim/visuals/board.ts.old | 697 ------------------------------ sim/visuals/led-candles.ts | 98 ----- sim/visuals/ledcandles.ts | 135 ++++++ 9 files changed, 350 insertions(+), 1226 deletions(-) create mode 100644 libs/atisa-menorah/lantern.ts create mode 100644 sim/state/ledcandles.ts delete mode 100644 sim/visuals/board-windsurf.ts.old delete mode 100644 sim/visuals/board.ts.old delete mode 100644 sim/visuals/led-candles.ts create mode 100644 sim/visuals/ledcandles.ts diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 94537d86..6b551159 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -90,12 +90,18 @@ }, { "id": "candles", - "x": 0, - "y": 0, - "r": 15, - "color": "neopixel", + "x": 284.647, + "y": 300, + "width": 100, + "height": 100, + "color": "0xff0000", "label": "CANDLES", - "numPixels": 7 + "numPixels": 7, + "type": "strip", + "startX": 256.64, + "startY": 356.252, + "endX": 312.257, + "endY": 356.252 } ], "candles": [ diff --git a/libs/atisa-menorah/lantern.ts b/libs/atisa-menorah/lantern.ts new file mode 100644 index 00000000..cd977ee7 --- /dev/null +++ b/libs/atisa-menorah/lantern.ts @@ -0,0 +1,80 @@ +//% color=#0fbc11 icon="\uf06d" weight=90 +namespace lantern { + let strip: light.LightStrip = light.onboardStrip(); + + // Initialize the NeoPixel strip if not already done + function initStrip() { + if (!strip) { + // Create a NeoPixel strip with 7 LEDs (one for each candle) + // Using pin P0 as the default data pin for the NeoPixel strip + strip = light.createStrip(pins.D0, 7); + strip.setBrightness(255); + } + return strip; + } + + /** + * Lights up a single candle with the specified color + * @param index which candle to light (0-6) + * @param color RGB color of the candle (e.g., 0xFF0000 for red) + */ + //% block="light candle at $index with color $color" + //% index.min=0 index.max=6 + //% color.shadow="colorNumberPicker" + export function lightCandle(index: number, color: number): void { + const s = initStrip(); + if (index >= 0 && index < s.length()) { + s.setPixelColor(index, color); + s.show(); + } + } + + /** + * Lights up all candles with the specified color + * @param color RGB color for all candles (e.g., 0xFF0000 for red) + */ + //% block="light all candles with color $color" + //% color.shadow="colorNumberPicker" + export function lightAllCandles(color: number): void { + const s = initStrip(); + s.setAll(color); + s.show(); + } + + /** + * Turns off all candles + */ + //% block="clear all candles" + export function clearCandles(): void { + lightAllCandles(0); // 0 means off + } + + /** + * Sets the brightness of the candles + * @param brightness a number between 0 (off) and 255 (full brightness) + */ + //% block="set candle brightness to $brightness" + //% brightness.min=0 brightness.max=255 + export function setBrightness(brightness: number): void { + const s = initStrip(); + s.setBrightness(brightness); + s.show(); + } +} + +// // Include the light namespace for NeoPixel support +// //% block="light" +// namespace light { +// export function createStrip(pin: DigitalPin, numleds: number): NeoPixelStrip { +// // This will be implemented by the NeoPixel extension +// return null; +// } + +// export class NeoPixelStrip { +// public setPixelColor(index: number, rgb: number): void {} +// public setAll(rgb: number): void {} +// public show(): void {} +// public setBrightness(brightness: number): void {} +// public length(): number { return 0; } +// } +// } diff --git a/libs/atisa-menorah/pxt.json b/libs/atisa-menorah/pxt.json index c7862d1a..35fb3a3a 100644 --- a/libs/atisa-menorah/pxt.json +++ b/libs/atisa-menorah/pxt.json @@ -5,17 +5,19 @@ "README.md", "device.d.ts", "config.ts", + "lantern.ts", "board.json", "board.svg" ], "core": true, "dependencies": { - "core---samd": "file:../core---samd", - "buttons": "file:../buttons", + "core": "file:../core", "light": "file:../light", + "pixel": "file:../pixel", + "core---samd": "file:../core---samd", "mixer---samd": "file:../mixer---samd", - "touch": "file:../touch", - "pixel": "file:../pixel" + "buttons": "file:../buttons", + "touch": "file:../touch" }, "public": true, "compileServiceVariant": "samd21", @@ -35,6 +37,15 @@ "touchd1", "light", "jacdac", - "music" - ] + "music", + "lantern" + ], + "simulator": { + "runtime": { + "include": "sim/register" + }, + "visualization": { + "include": "sim/visual" + } + } } \ No newline at end of file diff --git a/pxtarget.json b/pxtarget.json index 3d125f83..6d9b0765 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -8,7 +8,6 @@ "corepkg": "core", "bundleddirs": [ "libs/atisa-menorah", - "libs/neopixel", "libs/base", "libs/base---light", "libs/core", diff --git a/sim/state/ledcandles.ts b/sim/state/ledcandles.ts new file mode 100644 index 00000000..c545c15e --- /dev/null +++ b/sim/state/ledcandles.ts @@ -0,0 +1,107 @@ +/// + +console.log("LED Candles state module loaded"); + +namespace pxsim { + // Represents the state of an individual candle + export interface CandleState { + isLit: boolean; + brightness: number; + color?: string; // RGB color string (e.g., "#FF0000" for red) + } + + // Manages the state of all LED candles + export class LEDCandlesState { + private candles: CandleState[] = []; + private changed = true; + private pin: Pin; + private maxCandles: number; + + constructor(pin: Pin, maxCandles: number = 9) { + this.pin = pin; + this.maxCandles = maxCandles; + this.initializeCandles(); + } + + // Initialize all candles to unlit state + private initializeCandles() { + this.candles = []; + for (let i = 0; i < this.maxCandles; i++) { + this.candles.push({ + isLit: false, + brightness: 1.0, + color: "#FFA500" // Default to orange (candle color) + }); + } + this.changed = true; + } + + // Set the state of a specific candle + setCandleState(index: number, isLit: boolean, brightness: number = 1.0, color?: string): void { + if (index < 0 || index >= this.maxCandles) return; + + const candle = this.candles[index]; + if (candle.isLit !== isLit || + candle.brightness !== brightness || + (color && candle.color !== color)) { + + candle.isLit = isLit; + candle.brightness = Math.max(0, Math.min(1.0, brightness)); // Clamp between 0 and 1 + if (color) candle.color = color; + this.changed = true; + } + } + + // Toggle a candle's lit state + toggleCandle(index: number): void { + if (index < 0 || index >= this.maxCandles) return; + const candle = this.candles[index]; + this.setCandleState(index, !candle.isLit, candle.brightness, candle.color); + } + + // Set all candles to a specific state + setAllCandles(isLit: boolean, brightness: number = 1.0, color?: string): void { + this.candles.forEach((candle, index) => { + this.setCandleState(index, isLit, brightness, color); + }); + } + + // Get the current state of all candles + getCandleStates(): CandleState[] { + return [...this.candles]; // Return a copy to prevent direct modification + } + + // Get the state of a specific candle + getCandleState(index: number): CandleState | undefined { + if (index < 0 || index >= this.maxCandles) return undefined; + return { ...this.candles[index] }; // Return a copy + } + + // Check if any candle state has changed + hasChanged(): boolean { + return this.changed; + } + + // Clear the changed flag + clearChanged(): void { + this.changed = false; + } + + // Get the number of candles + getCandleCount(): number { + return this.maxCandles; + } + } + + // Register the LED candles state with the runtime + export function ledCandlesState(): LEDCandlesState { + return (board() as any).ledCandlesState as LEDCandlesState; + } +} + +// Register the LED candles state with the board +namespace pxsim.board { + export interface CommonBoard { + ledCandlesState: pxsim.LEDCandlesState; + } +} diff --git a/sim/visuals/board-windsurf.ts.old b/sim/visuals/board-windsurf.ts.old deleted file mode 100644 index 108a8ac5..00000000 --- a/sim/visuals/board-windsurf.ts.old +++ /dev/null @@ -1,419 +0,0 @@ -// SVG -``` - - - - - - - - - -``` - -// In board.ts, update the MetroBoardSvg class -export class MetroBoardSvg extends GenericBoardSvg { - public board: pxsim.DalBoard; - private onBoardLeds: BoardLed[]; - private onBoardNeopixels: BoardNeopixel[]; - private onBoardReset: BoardResetButton; - private onBoardButtons: BoardButton[]; - private onBoardTouchPads: BoardTouchButton[]; - private candleElements: SVGGElement[] = []; - private flameElements: SVGGElement[] = []; - private candleGlowFilter: SVGFilterElement; - - constructor(public props: MetroBoardProps) { - super(props); - - const el = this.getView().el; - this.addDefs(el); - - this.onBoardLeds = []; - this.onBoardNeopixels = []; - this.onBoardTouchPads = []; - this.onBoardButtons = []; - - // Initialize candle elements - this.initializeCandles(el); - - if (props && props.theme) - this.updateTheme(); - - if (props && props.runtime) { - this.board = this.props.runtime.board as pxsim.DalBoard; - this.board.updateSubscribers.push(() => this.updateState()); - this.updateState(); - } - } - - private initializeCandles(el: SVGElement) { - // Add glow filter for candle flames - const defs = svg.child(el, "defs", {}); - this.candleGlowFilter = svg.child(defs, "filter", { - id: "candleGlow", - x: "-50%", y: "-50%", width: "200%", height: "200%" - }) as SVGFilterElement; - svg.child(this.candleGlowFilter, "feGaussianBlur", { - stdDeviation: "4", - result: "coloredBlur" - }); - const feMerge = svg.child(this.candleGlowFilter, "feMerge", {}); - svg.child(feMerge, "feMergeNode", { in: "coloredBlur" }); - svg.child(feMerge, "feMergeNode", { in: "SourceGraphic" }); - - // Find and store candle elements - for (let i = 0; i < 9; i++) { // Assuming 9 candles for Hanukkah - const candleGroup = el.querySelector(`#candle${i}`) as SVGGElement; - if (candleGroup) { - this.candleElements[i] = candleGroup; - this.flameElements[i] = candleGroup.querySelector('.flame') as SVGGElement; - } - } - } - - private updateState() { - if (!this.board) return; - - // Update regular components - this.onBoardLeds.forEach(led => led.updateState()); - this.onBoardNeopixels.forEach(pixel => pixel.updateState()); - this.onBoardButtons.forEach(btn => btn.updateState()); - this.onBoardTouchPads.forEach(tp => tp.updateState()); - - // Update candle states - this.updateCandles(); - } - - private updateCandles() { - if (!this.board) return; - - // Get neopixel state - const neopixelPin = this.board.defaultNeopixelPin(); - if (!neopixelPin) return; - - const neopixelState = this.board.tryGetNeopixelState(neopixelPin.id); - if (!neopixelState) return; - - // Update each candle - for (let i = 0; i < 9; i++) { - const candle = this.candleElements[i]; - const flame = this.flameElements[i]; - if (!candle || !flame) continue; - - // Get color from neopixel (wrapping around if fewer pixels than candles) - const rgb = neopixelState.pixelColor(i % neopixelState.length); - - if (!rgb || (rgb[0] === 0 && rgb[1] === 0 && rgb[2] === 0)) { - // Candle is off - svg.fill(flame, 'none'); - svg.fill(candle, '#FFFFFF'); // Default candle color - continue; - } - - // Convert RGB to HSL for better color manipulation - const [h, s, l] = visuals.rgbToHsl([rgb[0], rgb[1], rgb[2]]); - - // Make flame brighter and more vibrant - const flameL = Math.max(l * 1.5, 85); - const flameS = Math.min(s * 1.2, 100); - const flameH = (h + 10) % 360; // Slight hue shift for more natural flame - - // Apply flame color with glow - svg.fill(flame, `hsl(${flameH}, ${flameS}%, ${flameL}%)`); - svg.filter(flame, 'url(#candleGlow)'); - - // Make candle body a dimmer, less saturated version - const candleL = l * 0.6; - const candleS = s * 0.5; - svg.fill(candle, `hsl(${h}, ${candleS}%, ${candleL}%)`); - } - } - - // ... rest of the class remains the same -} - -/// - -// In board.ts, update the MetroBoardSvg class - -// Add these imports at the top of the file if not already present -import { svg } from "./svg_util"; -import { visuals } from "./visuals"; - -// ... existing code ... - -export class MetroBoardSvg extends GenericBoardSvg { - public board: pxsim.DalBoard; - private onBoardLeds: BoardLed[]; - private onBoardNeopixels: BoardNeopixel[]; - private onBoardReset: BoardResetButton; - private onBoardButtons: BoardButton[]; - private onBoardTouchPads: BoardTouchButton[]; - private candleElements: SVGGElement[] = []; - private flameElements: SVGGElement[] = []; - private candleGlowFilter: SVGFilterElement; - - constructor(public props: MetroBoardProps) { - super(props); - - const el = this.getView().el; - this.addDefs(el); - this.initializeCandles(el); - - this.onBoardLeds = []; - this.onBoardNeopixels = []; - this.onBoardTouchPads = []; - this.onBoardButtons = []; - - if (props && props.theme) - this.updateTheme(); - - if (props && props.runtime) { - this.board = this.props.runtime.board as pxsim.DalBoard; - this.board.updateSubscribers.push(() => this.updateState()); - this.updateState(); - } - } - - private initializeCandles(el: SVGElement) { - // Add glow filter for candle flames - const defs = el.querySelector('defs') || svg.child(el, 'defs', {}); - - // Only add the glow filter if it doesn't exist - if (!el.querySelector('#candleGlow')) { - this.candleGlowFilter = svg.child(defs, "filter", { - id: "candleGlow", - x: "-50%", y: "-50%", - width: "200%", - height: "200%" - }) as SVGFilterElement; - - const feGaussianBlur = svg.child(this.candleGlowFilter, "feGaussianBlur", { - stdDeviation: "4", - result: "coloredBlur" - }); - - const feMerge = svg.child(this.candleGlowFilter, "feMerge", {}); - svg.child(feMerge, "feMergeNode", { in: "coloredBlur" }); - svg.child(feMerge, "feMergeNode", { in: "SourceGraphic" }); - } - - // Find and store candle elements - for (let i = 0; i < 9; i++) { // 9 candles for Hanukkah - const candleId = `candle${i}`; - const candleGroup = el.querySelector(`#${candleId}`) as SVGGElement; - - if (candleGroup) { - this.candleElements[i] = candleGroup; - - // Look for flame element (either direct child or nested) - let flame = candleGroup.querySelector('.flame') as SVGGElement; - if (!flame) { - // If no flame element exists, create one - flame = svg.child(candleGroup, 'g', { class: 'flame' }); - // Add a simple flame shape if none exists - if (!flame.querySelector('path, circle')) { - svg.child(flame, 'path', { - d: 'M-3,-10 L0,-20 L3,-10 Q0,-15 -3,-10', - fill: 'none', - stroke: 'none' - }); - } - } - this.flameElements[i] = flame; - } - } - } - - private updateState() { - if (!this.board) return; - - // Update regular components - this.onBoardLeds.forEach(led => led.updateState()); - this.onBoardNeopixels.forEach(pixel => pixel.updateState()); - this.onBoardButtons.forEach(btn => btn.updateState()); - this.onBoardTouchPads.forEach(tp => tp.updateState()); - - // Update candle states - this.updateCandles(); - } - - private updateCandles() { - if (!this.board) return; - - // Get neopixel state - const neopixelPin = this.board.defaultNeopixelPin(); - if (!neopixelPin) return; - - const neopixelState = this.board.tryGetNeopixelState(neopixelPin.id); - if (!neopixelState) return; - - // Update each candle - for (let i = 0; i < 9; i++) { - const candle = this.candleElements[i]; - const flame = this.flameElements[i]; - if (!candle || !flame) continue; - - // Get color from neopixel (wrapping around if fewer pixels than candles) - const rgb = neopixelState.pixelColor(i % neopixelState.length); - - if (!rgb || (rgb[0] === 0 && rgb[1] === 0 && rgb[2] === 0)) { - // Candle is off - svg.fill(flame, 'none'); - svg.fill(candle, '#FFFFFF'); // Default candle color - flame.style.display = 'none'; - continue; - } - - // Make flame visible - flame.style.display = ''; - - // Convert RGB to HSL for better color manipulation - const [h, s, l] = visuals.rgbToHsl([rgb[0], rgb[1], rgb[2]]); - - // Make flame brighter and more vibrant - const flameL = Math.max(l * 1.5, 85); - const flameS = Math.min(s * 1.2, 100); - const flameH = (h + 10) % 360; // Slight hue shift for more natural flame - - // Apply flame color with glow - const flameColor = `hsl(${flameH}, ${flameS}%, ${flameL}%)`; - flame.querySelectorAll('path, circle').forEach((el: SVGElement) => { - svg.fill(el, flameColor); - svg.stroke(el, `hsla(${flameH}, ${flameS}%, ${Math.min(flameL * 1.2, 100)}%, 0.7)`); - }); - - // Make candle body a dimmer, less saturated version - const candleL = l * 0.6; - const candleS = s * 0.5; - candle.querySelectorAll('.candle-body, rect, path:not(.flame *)').forEach((el: SVGElement) => { - if (!flame.contains(el)) { // Don't style flame elements - svg.fill(el, `hsl(${h}, ${candleS}%, ${candleL}%)`); - } - }); - } - } - - // ... rest of the existing methods ... -} - -``` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` \ No newline at end of file diff --git a/sim/visuals/board.ts.old b/sim/visuals/board.ts.old deleted file mode 100644 index 971a2e7f..00000000 --- a/sim/visuals/board.ts.old +++ /dev/null @@ -1,697 +0,0 @@ -// Type definitions for board elements -interface BoxDefinition { - x: number; - y: number; - w?: number; - h?: number; -} - -interface ButtonDefinition extends BoxDefinition { - label: string; -} - -interface TouchPadDefinition extends BoxDefinition { - label: string; -} - -interface CommonButton { - element: SVGElement; -} - -interface TouchButton { - element: SVGElement; -} - -interface CandleDefinition { - id: string; - x: number; - y: number; - r: number; - color: string; -} - -type BoardVisualDefinition = string | { - image?: string; - width?: number; - height?: number; - element?: string; - style?: string; - pins?: any; - leds?: any; - buttons?: any; - touchPads?: any; - candles?: CandleDefinition[]; -}; - -interface BoardDefinition { - visual?: string | BoardVisualDefinition; -} - -namespace pxsim.visuals { - const svg = pxsim.svg; - - export const VIEW_WIDTH = 372.3404255319149; - export const VIEW_HEIGHT = 361.70212765957444; - const TOP_MARGIN = 20; - const MID_MARGIN = 40; - const BOT_MARGIN = 20; - const PIN_LBL_SIZE = PIN_DIST * 0.7; - const PIN_LBL_HOVER_SIZE = PIN_LBL_SIZE * 1.5; - const SQUARE_PIN_WIDTH = PIN_DIST * 0.66666; - const SQUARE_PIN_HOVER_WIDTH = PIN_DIST * 0.66666 + PIN_DIST / 3.0; - - const STYLE = ` -.sim-board-pin { - stroke: #404040; - fill: #000000; -} -.sim-board-button { - stroke: #aaa; - stroke-width: 3px; - fill: #666; -} -.sim-board-button.pressed { - fill: #ee0; -} -.sim-board-button:hover { - stroke-width: 4px; - stroke: #ee0; - cursor: pointer; -} - ` - - export interface IBoardTheme { - accent?: string; - display?: string; - pin?: string; - pinTouched?: string; - pinActive?: string; - ledOn?: string; - ledOff?: string; - buttonOuter?: string; - buttonUps: string[]; - buttonDown?: string; - virtualButtonOuter?: string; - virtualButtonUp?: string; - virtualButtonDown?: string; - lightLevelOn?: string; - lightLevelOff?: string; - soundLevelOn?: string; - soundLevelOff?: string; - } - - export var themes: IBoardTheme[] = ["#3ADCFE"].map(accent => { - return { - accent: accent, - pin: "#D4AF37", - pinTouched: "#FFA500", - pinActive: "#FF5500", - ledOn: "#ff7777", - ledOff: "#fff", - buttonOuter: "#979797", - buttonUps: ["#000", "#000", "#000"], - buttonDown: "#FFA500", - virtualButtonDown: "#FFA500", - virtualButtonOuter: "#333", - virtualButtonUp: "#fff", - lightLevelOn: "yellow", - lightLevelOff: "#555", - soundLevelOn: "#7f8c8d", - soundLevelOff: "#555", - } - }); - - export function randomTheme(): IBoardTheme { - return themes[Math.floor(Math.random() * themes.length)]; - } - - export type ComputedBoardDimensions = { - scaleFn: (n: number) => number, - height: number, - width: number, - xOff: number, - yOff: number - }; - - export function getBoardDimensions(vis: BoardImageDefinition): ComputedBoardDimensions { - let scaleFn = (n: number) => n * (PIN_DIST / vis.pinDist); - let width = scaleFn(vis.width); - return { - scaleFn: scaleFn, - height: scaleFn(vis.height), - width: width, - xOff: (VIEW_WIDTH - width) / 2.0, - yOff: TOP_MARGIN - } - } - - export interface MetroBoardProps extends GenericBoardProps { - runtime?: pxsim.Runtime; - theme?: IBoardTheme; - disableTilt?: boolean; - } - - export class MetroBoardSvg extends GenericBoardSvg { - - public board: pxsim.DalBoard; - private onBoardLeds: BoardLed[]; - private onBoardNeopixels: BoardNeopixel[]; - private onBoardReset: BoardResetButton; - private onBoardButtons: BoardButton[]; - private onBoardTouchPads: BoardTouchButton[]; - - constructor(public props: MetroBoardProps) { - super(props); - - const el = this.getView().el; - this.addDefs(el); - - this.onBoardLeds = [] - this.onBoardNeopixels = []; - this.onBoardTouchPads = []; - this.onBoardButtons = []; - - // neopixels/leds - for (const l of props.visualDef.leds || []) { - if (l.color == "neopixel") { - const onBoardNeopixel = new BoardNeopixel(l.label, l.x, l.y, l.w || 0); - this.onBoardNeopixels.push(onBoardNeopixel); - el.appendChild(onBoardNeopixel.element); - } else { - const pin = pinByName(l.label); - if (pin) { - let bl = new BoardLed(l.x, l.y, l.color, pinByName(l.label), - l.w || 9, l.h || 8) - this.onBoardLeds.push(bl) - el.appendChild(bl.element) - } - } - } - this.onBoardNeopixels.sort((l, r) => { - const li = parseInt(l.name.replace(/^[^\d]*/, '')) || 0; - const ri = parseInt(r.name.replace(/^[^\d]*/, '')) || 0; - return li < ri ? -1 : li > ri ? 1 : 0; - }) - - // reset button - if (props.visualDef.reset) { - this.onBoardReset = new BoardResetButton(props.visualDef.reset) - el.appendChild(this.onBoardReset.element) - } - - // touch pads - for (const l of props.visualDef.touchPads || []) { - const pin = pxsim.pinIds[l.label]; - if (!pin) { - console.error(`touch pin ${pin} not found`) - continue; - } - const tp = new BoardTouchButton(l, pin); - this.onBoardTouchPads.push(tp); - el.appendChild(tp.element); - } - - // regular buttons - for (const l of props.visualDef.buttons || []) { - const tp = new BoardButton(l); - this.onBoardButtons.push(tp); - el.appendChild(tp.element); - } - - if (props && props.theme) - this.updateTheme(); - - if (props && props.runtime) { - this.board = this.props.runtime.board as pxsim.DalBoard; - this.board.updateSubscribers.push(() => this.updateState()); - this.updateState(); - } - - - } - - public updateTheme() { - } - - public updateState() { - this.onBoardLeds.forEach(l => l.updateState()); - if (this.board.neopixelPin) { - const state = this.board.neopixelState(this.board.neopixelPin.id); - if (state.buffer) { - for (let i = 0; i < this.onBoardNeopixels.length; ++i) { - const rgb = state.pixelColor(i) - if (rgb !== null) - this.onBoardNeopixels[i].setColor(rgb as any); - } - } - } - } - - private addDefs(el: SVGElement) { - const defs = svg.child(el, "defs", {}); - - let neopixelglow = svg.child(defs, "filter", { id: "neopixelglow", x: "-200%", y: "-200%", width: "400%", height: "400%" }); - svg.child(neopixelglow, "feGaussianBlur", { stdDeviation: "4.3", result: "coloredBlur" }); - let neopixelmerge = svg.child(neopixelglow, "feMerge", {}); - svg.child(neopixelmerge, "feMergeNode", { in: "coloredBlur" }) - svg.child(neopixelmerge, "feMergeNode", { in: "SourceGraphic" }) - - const style = svg.child(el, "style", {}); - style.textContent = STYLE; - } - } - - class BoardResetButton { - element: SVGElement; - constructor(p: BoxDefinition) { - p.w = p.w || 15; - p.h = p.h || 15; - this.element = svg.elt("circle", { - cx: p.x + p.w / 2, - cy: p.y + p.h / 2, - r: Math.max(p.w, p.h) / 2, - class: "sim-board-button" - }) as SVGCircleElement - svg.title(this.element, "RESET"); - // hooking up events - pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { - pxsim.U.addClass(this.element, "pressed"); - pxsim.Runtime.postMessage({ - type: "simulator", - command: "restart" - }) - })); - this.element.addEventListener(pointerEvents.leave, ev => { - pxsim.U.removeClass(this.element, "pressed"); - }) - this.element.addEventListener(pointerEvents.up, ev => { - pxsim.U.removeClass(this.element, "pressed"); - }) - } - } - - class BoardLed { - private colorOff = "#aaa" - private backElement: SVGElement; - private ledElement: SVGElement; - element: SVGElement; - - constructor(x: number, y: number, private colorOn: string, private pin: Pin, w: number, h: number) { - this.backElement = svg.elt("rect", { x, y, width: w, height: h, fill: this.colorOff }); - this.ledElement = svg.elt("rect", { x, y, width: w, height: h, fill: this.colorOn, opacity: 0 }); - svg.filter(this.ledElement, `url(#neopixelglow)`); - this.element = svg.elt("g", { class: "sim-led" }); - this.element.appendChild(this.backElement); - this.element.appendChild(this.ledElement); - } - - updateTheme(colorOff: string, colorOn: string) { - if (colorOff) { - this.colorOff = colorOff; - } - if (colorOn) { - this.colorOn = colorOn; - } - } - - updateState() { - const opacity = this.pin.mode & PinFlags.Digital ? (this.pin.value > 0 ? 1 : 0) - : 0.1 + Math.max(0, Math.min(1023, this.pin.value)) / 1023 * 0.8; - this.ledElement.setAttribute("opacity", opacity.toString()) - } - } - - interface CandleDefinition { - id: string; - x: number; - y: number; - r: number; - color: string; - } - - interface BoardVisualDefinition extends BoardImageDefinition { - candles?: CandleDefinition[]; - } - - class BoardNeopixel { - name: string; - element: SVGGElement; - private candles: Array<{ - element: SVGCircleElement; - defaultColor: string; - index: number; // 0-7 for the 8 candles - }> = []; - private pixelColors: {[index: number]: [number, number, number]} = {}; - private pixelCount: number = 0; - private state: any; // Using any to avoid TypeScript issues with neopixelState - - constructor(name: string, x: number, y: number, r: number) { - this.name = name; - this.element = svg.elt("g") as SVGGElement; - this.element.setAttribute("class", "neopixel"); - - // Create a circle for the neopixel (hidden by default) - const circle = svg.elt("circle", { - cx: x, - cy: y, - r: r, - fill: "#000000" - }) as SVGCircleElement; - circle.style.display = "none"; - this.element.appendChild(circle); - - // Create candles if defined in board definition - const board = (window as any).board as any; - if (board?.boardDefinition?.visual) { - const visualDef = board.boardDefinition.visual; - if (typeof visualDef === 'object' && 'candles' in visualDef && Array.isArray(visualDef.candles)) { - this.createCandles(visualDef.candles); - } - } - - // Initialize neopixel state - this.initNeoPixelState(); - } - - private initNeoPixelState() { - // Try to get the neopixel state - this.state = (window as any).board?.neopixelState?.(this.name); - - if (this.state) { - // Override the update method to ensure our visualization updates - const originalUpdate = this.state.update; - this.state.update = () => { - if (originalUpdate) originalUpdate.call(this.state); - this.updateFromState(); - }; - - // Initialize with current state - this.updateFromState(); - } - } - - private createCandles(candleDefs: CandleDefinition[]) { - // Separate shamash from regular candles - const regularCandles = candleDefs.filter(c => !c.id.includes('shamash')); - const shamash = candleDefs.find(c => c.id.includes('shamash')); - - // Sort regular candles by x-coordinate (left to right) - const sortedCandles = [...regularCandles].sort((a, b) => a.x - b.x); - - // Create regular candles (indices 0-6) - sortedCandles.forEach((def, i) => { - if (i >= 7) return; // Only take first 7 candles - - const candle = svg.elt("circle", { - cx: def.x, - cy: def.y, - r: def.r, - fill: def.color, - class: `candle ${def.id}` - }) as SVGCircleElement; - - svg.filter(candle, `url(#neopixelglow)`); - - this.candles.push({ - element: candle, - defaultColor: def.color, - index: i - }); - - this.pixelColors[i] = [0, 0, 0]; - this.pixelCount = Math.max(this.pixelCount, i + 1); - this.element.appendChild(candle); - }); - - // Add shamash as index 7 if it exists - if (shamash) { - const candle = svg.elt("circle", { - cx: shamash.x, - cy: shamash.y, - r: shamash.r, - fill: shamash.color, - class: `candle ${shamash.id} shamash` - }) as SVGCircleElement; - - svg.filter(candle, `url(#neopixelglow)`); - - this.candles.push({ - element: candle, - defaultColor: shamash.color, - index: 7 - }); - - this.pixelColors[7] = [0, 0, 0]; - this.pixelCount = Math.max(this.pixelCount, 8); - this.element.appendChild(candle); - } - } - - /** - * Dim a hex color by a specific factor - * @param color Hex color string (e.g., "#FF0000") - * @param factor Dim factor (0-1, where 1 is original color, 0 is black) - */ - private dimColor(color: string, factor: number): string { - // Remove the '#' if present - const hex = color.startsWith('#') ? color.slice(1) : color; - - // Parse the hex color into RGB components - const r = parseInt(hex.substring(0, 2), 16); - const g = parseInt(hex.substring(2, 4), 16); - const b = parseInt(hex.substring(4, 6), 16); - - // Dim each component by the factor - const dimR = Math.round(r * factor); - const dimG = Math.round(g * factor); - const dimB = Math.round(b * factor); - - // Convert back to hex - return this.rgbToHex(dimR, dimG, dimB); - } - - /** - * Convert RGB values (0-255) to CSS hex color - */ - private rgbToHex(r: number, g: number, b: number): string { - return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); - } - - /** - * Set the color of a specific pixel (candle) - * @param pixelIndex Index of the pixel (0-7 for the 8 candles) - * @param rgb RGB color as [r, g, b] (0-255) - */ - setPixelColor(pixelIndex: number, r: number, g: number, b: number) { - if (pixelIndex < 0 || pixelIndex >= this.pixelCount) return; - - // Store the color and update immediately - this.pixelColors[pixelIndex] = [r, g, b]; - this.updateCandle(pixelIndex); - } - - /** - * Set all pixels to the same color - * @param rgb RGB color as [r, g, b] (0-255) - */ - setAll(r: number, g: number, b: number) { - // Update all pixels at once - for (let i = 0; i < this.pixelCount; i++) { - this.pixelColors[i] = [r, g, b]; - this.updateCandle(i); - } - } - - /** - * Update the visual representation of a candle based on its pixel color - * @param pixelIndex Index of the pixel/candle to update - */ - private updateCandle(pixelIndex: number) { - const candle = this.candles.find(c => c.index === pixelIndex); - if (!candle) return; - - const [r, g, b] = this.pixelColors[pixelIndex] || [0, 0, 0]; - const isShamash = candle.element.classList.contains('shamash'); - - if (isShamash) { - // Special handling for shamash - keep yellow tint - if (r === 0 && g === 0 && b === 0) { - // Dim when off - const dimmedColor = this.dimColor(candle.defaultColor, 0.3); - svg.fill(candle.element, dimmedColor); - } else { - // Mix with yellow to maintain the shamash appearance - const [or, og, ob] = this.hexToRgb(candle.defaultColor); - const mixed = this.mixColors([r, g, b], [or, og, ob], 0.5); - svg.fill(candle.element, this.rgbToHex(...mixed)); - } - return; - } - - // Regular candle behavior - if (r === 0 && g === 0 && b === 0) { - // Dim when off - const dimmedColor = this.dimColor(candle.defaultColor, 0.1); - svg.fill(candle.element, dimmedColor); - } else { - // Set to the specified color - const color = this.rgbToHex(r, g, b); - svg.fill(candle.element, color); - - // Add glow effect based on brightness - const brightness = (0.299 * r + 0.587 * g + 0.114 * b) / 2.55; - const glowIntensity = Math.max(0.3, brightness / 100); - const glowColor = this.rgbToHex( - Math.min(255, r + 100 * glowIntensity), - Math.min(255, g + 100 * glowIntensity), - Math.min(255, b + 100 * glowIntensity) - ); - candle.element.style.filter = `drop-shadow(0 0 ${5 * glowIntensity}px ${glowColor})`; - } - } - - /** - * Update candle colors from the neopixel state - */ - private updateFromState() { - if (!this.state) return; - - try { - // Use requestAnimationFrame to batch updates - requestAnimationFrame(() => { - // Update each pixel - for (let i = 0; i < this.pixelCount; i++) { - const colors = this.state.pixelColor(i); - if (colors && colors.length >= 3) { - this.setPixelColor(i, colors[0], colors[1], colors[2]); - } - } - }); - } catch (e) { - console.error('Error updating neopixel state:', e); - } - } - - /** - * Helper to convert hex color to RGB - */ - private hexToRgb(hex: string): [number, number, number] { - const r = parseInt(hex.slice(1, 3), 16); - const g = parseInt(hex.slice(3, 5), 16); - const b = parseInt(hex.slice(5, 7), 16); - return [r, g, b]; - } - - /** - * Mix two colors with a given ratio (0-1) - */ - private mixColors(rgb1: [number, number, number], rgb2: [number, number, number], ratio: number): [number, number, number] { - return [ - Math.round(rgb1[0] * (1 - ratio) + rgb2[0] * ratio), - Math.round(rgb1[1] * (1 - ratio) + rgb2[1] * ratio), - Math.round(rgb1[2] * (1 - ratio) + rgb2[2] * ratio) - ]; - } - - // Keep the old setColor for backward compatibility - // This handles both setColor([r,g,b]) and setColor(r,g,b) for compatibility - setColor(r: number | number[], g?: number, b?: number) { - let red: number, green: number, blue: number; - - if (Array.isArray(r)) { - // Called with array: [r,g,b] - [red, green, blue] = r; - } else if (g !== undefined && b !== undefined) { - // Called with individual components - red = r as number; - green = g; - blue = b; - } else { - // Invalid arguments, default to black - red = green = blue = 0; - } - - this.setAll(red, green, blue); - - // Update the neopixel state if available - if (this.state) { - const stride = (this.state as any).stride || 3; - for (let i = 0; i < this.pixelCount; i++) { - (this.state as any).setBufferRGB(i * stride, red, green, blue); - } - // Trigger update if available - if (typeof (this.state as any).update === 'function') { - (this.state as any).update(); - } - } - } - } - - class BoardButton { - element: SVGElement; - def: ButtonDefinition; - button: CommonButton; - constructor(def: ButtonDefinition) { - this.def = def; - def.w = def.w || 15; - def.h = def.h || 15; - this.element = svg.elt("circle", { - cx: def.x + def.w / 2, - cy: def.y + def.h / 2, - r: Math.max(def.w, def.h) / 2, - class: "sim-board-button" - }) as SVGCircleElement - svg.title(this.element, def.label); - // resolve button - this.button = def.index !== undefined - ? pxsim.pxtcore.getButton(def.index) - : pxsim.pxtcore.getButtonByPin(pxsim.pinIds[def.label]); - // hooking up events - pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { - this.button.setPressed(true); - pxsim.U.addClass(this.element, "pressed"); - })); - this.element.addEventListener(pointerEvents.leave, ev => { - pxsim.U.removeClass(this.element, "pressed"); - this.button.setPressed(false); - }) - this.element.addEventListener(pointerEvents.up, ev => { - pxsim.U.removeClass(this.element, "pressed"); - this.button.setPressed(false); - }) - } - } - - class BoardTouchButton { - element: SVGElement; - def: TouchPadDefinition; - button: TouchButton; - constructor(def: TouchPadDefinition, pinId: number) { - this.def = def; - def.w = def.w || 15; - def.h = def.h || 15; - this.element = svg.elt("circle", { - cx: def.x + def.w / 2, - cy: def.y + def.h / 2, - r: Math.max(def.w, def.h) / 2, - class: "sim-board-button" - }) as SVGCircleElement - svg.title(this.element, def.label); - // resolve button - this.button = pxsim.pxtcore.getTouchButton(pinId); - // hooking up events - pointerEvents.down.forEach(evid => this.element.addEventListener(evid, ev => { - this.button.setPressed(true); - pxsim.U.addClass(this.element, "pressed"); - })); - this.element.addEventListener(pointerEvents.leave, ev => { - pxsim.U.removeClass(this.element, "pressed"); - this.button.setPressed(false); - }) - this.element.addEventListener(pointerEvents.up, ev => { - pxsim.U.removeClass(this.element, "pressed"); - this.button.setPressed(false); - }) - } - } -} \ No newline at end of file diff --git a/sim/visuals/led-candles.ts b/sim/visuals/led-candles.ts deleted file mode 100644 index 609c6655..00000000 --- a/sim/visuals/led-candles.ts +++ /dev/null @@ -1,98 +0,0 @@ -/// - -namespace pxsim.visuals { - export interface ICandleTheme { - candleOn?: string; - candleOff?: string; - } - - export const defaultCandleTheme: ICandleTheme = { - candleOn: "#ff8c1a", // Bright orange for lit candles - candleOff: "#4d4d4d" // Dark gray for unlit candles - }; - - export class CandleView { - public element: SVGGElement; - private candles: SVGCircleElement[] = []; - private theme: ICandleTheme; - private board: pxsim.DalBoard; - - constructor() { - this.theme = {...defaultCandleTheme}; - this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; - this.board = (window as any).board as pxsim.DalBoard; - this.createCandles(); - } - - private createCandles() { - // Create 7 candles (6 regular + 1 shamash, but we'll handle all the same for now) - for (let i = 0; i < 7; i++) { - const candle = svg.elt("circle", { - r: 15, - class: "sim-candle", - fill: this.theme.candleOff - }) as SVGCircleElement; - - // Position will be set by the parent component - this.candles.push(candle); - this.element.appendChild(candle); - } - } - - private updateCandles() { - if (!this.candles.length) return; - - // Update all candles to their current theme state - this.candles.forEach(candle => { - // If we have a board and it's initialized, use the NeoPixel state - if (this.board) { - const index = this.candles.indexOf(candle); - const neopixel = this.board.neopixelState(index); - if (neopixel) { - const rgb = neopixel.pixelColor(0); - if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { - // If pixel has color, use it - svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); - return; - } - } - } - - // Otherwise use the theme's off color - svg.fill(candle, this.theme.candleOff); - }); - } - - public updateTheme(theme?: ICandleTheme) { - if (theme) { - this.theme = {...defaultCandleTheme, ...theme}; - } - this.updateCandles(); - } - - public updateState() { - if (!this.board) return; - - const neopixel = this.board.neopixelState(0); // Get the single NeoPixel strip - if (!neopixel) return; - - this.candles.forEach((candle, index) => { - const rgb = neopixel.pixelColor(index); // Get color for this candle's position - if (rgb && (rgb[0] > 0 || rgb[1] > 0 || rgb[2] > 0)) { - svg.fill(candle, `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`); - } else { - svg.fill(candle, this.theme.candleOff); - } - }); - } - - public setPositions(positions: {x: number, y: number}[]) { - positions.forEach((pos, index) => { - if (index < this.candles.length) { - this.candles[index].setAttribute('cx', pos.x.toString()); - this.candles[index].setAttribute('cy', pos.y.toString()); - } - }); - } - } -} \ No newline at end of file diff --git a/sim/visuals/ledcandles.ts b/sim/visuals/ledcandles.ts new file mode 100644 index 00000000..1e216acf --- /dev/null +++ b/sim/visuals/ledcandles.ts @@ -0,0 +1,135 @@ +/// + +console.log("LED Candles visuals module loaded"); + +namespace pxsim.visuals { + export interface ICandleTheme { + candleOn?: string; // Color when candle is lit + candleOff?: string; // Color when candle is unlit + } + + export const defaultCandleTheme: ICandleTheme = { + candleOn: "#ff9933", // Orange candle + candleOff: "#4d4d4d", // Dark gray + }; + + export function mkCandlesSvg(xy: Coord, count: number = 7, spacing: number = 30, candleRadius: number = 10): + { el: SVGGElement, candles: SVGGElement[] } { + + const group = svg.elt("g") as SVGGElement; + const candles: SVGGElement[] = []; + + const [x, y] = xy; + + for (let i = 0; i < count; i++) { + // Candle element - using circle for simplicity, can be changed to rect if needed + const candle = svg.elt("circle", { + class: 'sim-candle', + cx: x + i * spacing, + cy: y, + r: candleRadius, + fill: defaultCandleTheme.candleOff + }) as unknown as SVGGElement; + + candles.push(candle); + group.appendChild(candle); + } + + return { el: group, candles }; + } + + export class CandleView { + public element: SVGGElement; + private candles: SVGGElement[] = []; + private theme: ICandleTheme; + private state: pxsim.LEDCandlesState; + private changed = true; + private animationFrame: number; + + constructor() { + this.theme = { ...defaultCandleTheme }; + this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; + this.state = pxsim.ledCandlesState(); + this.initialize(); + this.startAnimation(); + } + + private initialize() { + const { el, candles } = mkCandlesSvg( + [0, 0], + this.state.getCandleCount() + ); + + this.candles = candles; + this.element.appendChild(el); + + // Initial update + this.updateState(); + } + + private startAnimation() { + const animate = () => { + if (this.changed || this.state.hasChanged()) { + this.updateState(); + this.changed = false; + this.state.clearChanged(); + } + this.animationFrame = requestAnimationFrame(animate); + }; + this.animationFrame = requestAnimationFrame(animate); + } + + private stopAnimation() { + if (this.animationFrame) { + cancelAnimationFrame(this.animationFrame); + this.animationFrame = undefined; + } + } + + public updateState() { + if (!this.state) return; + + const count = Math.min(this.state.getCandleCount(), this.candles.length); + + for (let i = 0; i < count; i++) { + const candleState = this.state.getCandleState(i); + if (!candleState) continue; + + const { isLit, brightness, color } = candleState; + const baseColor = color || this.theme.candleOn; + + // Update candle + const candle = this.candles[i]; + svg.fill(candle, isLit ? baseColor : this.theme.candleOff); + + // Apply brightness/opacity + candle.style.opacity = isLit ? brightness.toString() : '0'; + } + } + + public updateTheme(theme?: Partial) { + if (theme) { + this.theme = { ...defaultCandleTheme, ...theme }; + this.changed = true; + } + } + + public setPositions(positions: {x: number, y: number}[]) { + positions.forEach((pos, i) => { + if (i < this.candles.length) { + const candle = this.candles[i] as SVGCircleElement; + candle.cx.baseVal.value = pos.x; + candle.cy.baseVal.value = pos.y; + } + }); + this.changed = true; + } + + public dispose() { + this.stopAnimation(); + if (this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } + } + } +} \ No newline at end of file From ecdd1a8e1bb906fb44c45267e73a6675b0b93115 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Mon, 28 Jul 2025 18:54:11 -0700 Subject: [PATCH 14/19] attempted to spoof candles through DAL --- docs/projects.md | 7 +- docs/projects/SUMMARY.md | 3 +- libs/atisa-menorah/board.json | 142 +++++++++++++++++++++------------- libs/atisa-menorah/config.ts | 82 ++++++++++---------- libs/atisa-menorah/lantern.ts | 4 +- libs/atisa-menorah/pxt.json | 10 ++- maker.code-workspace | 3 + package.json | 3 +- sim/dalboard.ts | 8 ++ sim/state/ledcandles.ts | 19 +++-- sim/visuals/board.ts | 9 ++- sim/visuals/ledcandles.ts | 2 +- 12 files changed, 176 insertions(+), 116 deletions(-) diff --git a/docs/projects.md b/docs/projects.md index 801ca101..f4356840 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -1,7 +1,3 @@ - - - - # Projects ```codecard @@ -56,4 +52,5 @@ [Kwanzaa](/projects/kwanzaa), [My Gallery](/projects/my-gallery), [Adafruit](/boards/adafruit), -[Analog IO](/projects/analog-io) \ No newline at end of file +[Analog IO](/projects/analog-io) + diff --git a/docs/projects/SUMMARY.md b/docs/projects/SUMMARY.md index 428e18e9..4e9d5047 100644 --- a/docs/projects/SUMMARY.md +++ b/docs/projects/SUMMARY.md @@ -1,6 +1,5 @@ - - # Projects + * [Parole](/projects/parole) * [ex1](/projects/parole/ex1) * [ex2](/projects/parole/ex2) diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 6b551159..783dac7b 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -3,69 +3,118 @@ "visual": { "image": "pkg://board.svg", "useCrocClips": false, - "width": 409.62432861328125, - "height": 485.56903076171875, + "width": 409.6239929199219, + "height": 485.5690002441406, "pinDist": 15, "pinBlocks": [ { - "x": 227.7543777712405, - "y": 369.6968222703879, + "x": 10.85988863653548, + "y": 3.141045080908931, + "labels": [ + "CANDLE0" + ] + }, + { + "x": 67.06181081486271, + "y": 3.141045080908931, + "labels": [ + "CANDLE1" + ] + }, + { + "x": 121.4207186561824, + "y": 3.141045080908931, + "labels": [ + "CANDLE2" + ] + }, + { + "x": 193.1495027572595, + "y": 3.141045080908931, + "labels": [ + "CANDLE3" + ] + }, + { + "x": 262.04441259686496, + "y": 3.141045080908931, + "labels": [ + "CANDLE4" + ] + }, + { + "x": 320.7433152108822, + "y": 3.141045080908931, + "labels": [ + "CANDLE5" + ] + }, + { + "x": 372.9421273706446, + "y": 2.923037400420722, + "labels": [ + "CANDLE6" + ] + }, + { + "x": 227.75053162155578, + "y": 369.6883747857013, "labels": [ "VBAT" ] }, { - "x": 208.02269350583958, - "y": 369.6968222703879, + "x": 208.02239858132688, + "y": 369.6883747857013, "labels": [ "GND" ] }, { - "x": 188.272298156588, - "y": 369.6968222703879, + "x": 188.26454681925023, + "y": 369.6883747857013, "labels": [ "A4_D4_TX_MOSI" ] }, { - "x": 168.53436923850828, - "y": 369.6968222703879, + "x": 168.5363956357235, + "y": 369.6883747857013, "labels": [ "A3_D3_RX_SCK" ] }, { - "x": 148.80268497310735, - "y": 468.1922676403129, + "x": 148.79833821158084, + "y": 468.1893829606932, "labels": [ "3V3" ] }, { - "x": 168.53436923850828, - "y": 468.1922676403129, + "x": 168.5363956357235, + "y": 468.1893829606932, "labels": [ "A1_D2_SCL_MISO" ] }, { - "x": 188.272298156588, - "y": 468.1922676403129, + "x": 188.26454681925023, + "y": 468.1893829606932, "labels": [ "A0_D1" ] }, { - "x": 208.02269350583958, - "y": 468.1922676403129, + "x": 208.02239858132688, + "y": 468.1893829606932, "labels": [ "A2_D0_SDA" ] }, { - "x": 114.9234312624489, - "y": 412.6453022009505, + "x": 114.92062820192746, + "y": 412.6419839288162, "labels": [ "RESET" ] @@ -73,50 +122,33 @@ ], "leds": [ { - "x": 282.4396476240902, - "y": 466.13103997939635, - "w": 6.264919207243066, - "h": 6.264880191660064, + "x": 282.4364270480412, + "y": 466.1283975684879, + "w": 6.272183418546294, + "h": 6.272120519638412, "color": "#ff0000", "label": "LED" }, { - "x": 189.12175391438566, - "y": 405.53091929957327, - "w": 11.136937754336072, - "h": 10.056290621329891, + "x": 189.1166830884958, + "y": 405.527632755068, + "w": 11.147242187588585, + "h": 10.057191785158693, "color": "neopixel", "label": "NEOPIXEL" - }, - { - "id": "candles", - "x": 284.647, - "y": 300, - "width": 100, - "height": 100, - "color": "0xff0000", - "label": "CANDLES", - "numPixels": 7, - "type": "strip", - "startX": 256.64, - "startY": 356.252, - "endX": 312.257, - "endY": 356.252 } ], - "candles": [ - {"x": 256.64, "y": 356.252, "index": 0}, - {"x": 265.278, "y": 356.252, "index": 1}, - {"x": 273.629, "y": 356.252, "index": 2}, - {"x": 284.647, "y": 356.252, "index": 3}, - {"x": 295.231, "y": 356.252, "index": 4}, - {"x": 304.249, "y": 356.252, "index": 5}, - {"x": 312.257, "y": 356.214, "index": 6} - ], "touchPads": [], "buttons": [] }, "gpioPinMap": { + "CANDLE0": "CANDLE0", + "CANDLE1": "CANDLE1", + "CANDLE2": "CANDLE2", + "CANDLE3": "CANDLE3", + "CANDLE4": "CANDLE4", + "CANDLE5": "CANDLE5", + "CANDLE6": "CANDLE6", "VBAT": "VBAT", "GND": "GND", "A4_D4_TX_MOSI": "A4_D4_TX_MOSI", @@ -143,6 +175,7 @@ "D0": "A2_D0_SDA", "SDA": "A2_D0_SDA", "LED": "LED", + "RESET": "RESET", "NEOPIXEL": "NEOPIXEL" }, "groundPins": [ @@ -157,8 +190,7 @@ "SCL": "SCL" }, "onboardComponents": [ - "pixel", - "neopixel" + "pixel" ], "marginWhenBreadboarding": [ 0, @@ -171,4 +203,4 @@ "MISO": "MISO", "SCK": "SCK" } -} +} \ No newline at end of file diff --git a/libs/atisa-menorah/config.ts b/libs/atisa-menorah/config.ts index 8459cdce..abce0412 100644 --- a/libs/atisa-menorah/config.ts +++ b/libs/atisa-menorah/config.ts @@ -1,45 +1,45 @@ - namespace config { - // Onboard DotStar LED - export const PIN_ONBOARD_DOTSTAR_DATA = DAL.PA00; - export const PIN_ONBOARD_DOTSTAR_CLOCK = DAL.PA01; - export const NUM_ONBOARD_DOTSTARS = 1; - + // Map physical pins to logical pins using PXT core constants + // These map to the definitions in atisa_menorah.h + + // Candle pins + export const CANDLE0 = DAL.CFG_CANDLE0; + export const CANDLE1 = DAL.CFG_CANDLE1; + export const CANDLE2 = DAL.CFG_CANDLE2; + export const CANDLE3 = DAL.CFG_CANDLE3; + export const CANDLE4 = DAL.CFG_CANDLE4; + export const CANDLE5 = DAL.CFG_CANDLE5; + export const CANDLE6 = DAL.CFG_CANDLE6; + + // Power pins + export const VBAT = DAL.CFG_PIN_VBAT; + + // Analog/Digital pins + export const PIN_A0 = DAL.CFG_PIN_A0; + export const PIN_A1 = DAL.CFG_PIN_A1; + export const PIN_A2 = DAL.CFG_PIN_A2; + export const PIN_A3 = DAL.CFG_PIN_A3; + export const PIN_A4 = DAL.CFG_PIN_A4; + // Digital pins - export const PIN_D0 = DAL.PA08; - export const PIN_D1 = DAL.PA02; - export const PIN_D2 = DAL.PA09; - export const PIN_D3 = DAL.PA07; - export const PIN_D4 = DAL.PA06; - export const PIN_D13 = DAL.PA10; - - // Analog pins - export const PIN_A0 = PIN_D1; - export const PIN_A1 = PIN_D2; - export const PIN_A2 = PIN_D4; - export const PIN_A3 = PIN_D3; - export const PIN_A4 = PIN_D0; - - // LED - export const PIN_LED = PIN_D13; - + export const PIN_D0 = DAL.CFG_PIN_D0; + export const PIN_D1 = DAL.CFG_PIN_D1; + export const PIN_D2 = DAL.CFG_PIN_D2; + export const PIN_D3 = DAL.CFG_PIN_D3; + export const PIN_D4 = DAL.CFG_PIN_D4; + // I2C pins - export const PIN_SDA = PIN_D0; - export const PIN_SCL = PIN_D2; - + export const PIN_SDA = DAL.CFG_PIN_SDA; + export const PIN_SCL = DAL.CFG_PIN_SCL; + // SPI pins - export const PIN_SCK = PIN_D3; - export const PIN_MISO = PIN_D2; - export const PIN_MOSI = PIN_D4; - - // UART pins - export const PIN_RX = PIN_D3; - export const PIN_TX = PIN_D4; - - // Neopixel configuration - export const PIN_NEOPIXEL = DAL.PB23; - export const NUM_NEOPIXELS = 7; // 7 candles + 1 shamash - - // Not supported - export const PIN_JACK_TX = PIN_TX; -} + export const PIN_MOSI = DAL.CFG_PIN_MOSI; + export const PIN_MISO = DAL.CFG_PIN_MISO; + export const PIN_SCK = DAL.CFG_PIN_SCK; + + // Built-in LED and Neopixel + export const PIN_LED = DAL.CFG_PIN_LED; + export const PIN_NEOPIXEL = DAL.CFG_PIN_NEOPIXEL; + export const NUM_NEOPIXEL = 1; + // additional pins to look for: SPI, I2C, Flash +} \ No newline at end of file diff --git a/libs/atisa-menorah/lantern.ts b/libs/atisa-menorah/lantern.ts index cd977ee7..e1a09076 100644 --- a/libs/atisa-menorah/lantern.ts +++ b/libs/atisa-menorah/lantern.ts @@ -1,6 +1,6 @@ -//% color=#0fbc11 icon="\uf06d" weight=90 +//% color="#FF5533" icon="\uf06d" weight=90 namespace lantern { - let strip: light.LightStrip = light.onboardStrip(); + let strip: light.LightStrip; // Initialize the NeoPixel strip if not already done function initStrip() { diff --git a/libs/atisa-menorah/pxt.json b/libs/atisa-menorah/pxt.json index 35fb3a3a..6f955b26 100644 --- a/libs/atisa-menorah/pxt.json +++ b/libs/atisa-menorah/pxt.json @@ -9,9 +9,17 @@ "board.json", "board.svg" ], + "additionalFilePath": "./include", + "include": [ + "atisa_menorah.h" + ], "core": true, + "dalDTS": { + "includeDirs": [ + "include" + ] + }, "dependencies": { - "core": "file:../core", "light": "file:../light", "pixel": "file:../pixel", "core---samd": "file:../core---samd", diff --git a/maker.code-workspace b/maker.code-workspace index f5bdab99..9a04eaa4 100644 --- a/maker.code-workspace +++ b/maker.code-workspace @@ -15,6 +15,9 @@ { "path": "../pxt-microbit" }, + { + "path": "../pxt-sample" + }, { "path": "." } diff --git a/package.json b/package.json index dc481dc8..14403ba7 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,9 @@ "typescript": "4.8.3" }, "dependencies": { + "node-hid": "^3.2.0", "pxt-common-packages": "12.3.30", - "pxt-core": "11.4.8", + "pxt-core": "11.4.8", "usb": "^2.15.0" }, "scripts": { diff --git a/sim/dalboard.ts b/sim/dalboard.ts index d38eddef..c3c55ee3 100644 --- a/sim/dalboard.ts +++ b/sim/dalboard.ts @@ -50,6 +50,7 @@ namespace pxsim { lcdState: LCDState; radioState: RadioState; controlMessageState: ControlMessageState; + ledCandlesState: any; // Will be of type LEDCandlesState constructor(public boardDefinition: BoardDefinition) { super(); @@ -177,6 +178,13 @@ namespace pxsim { this.builtinParts["pixels"] = (pin: Pin) => { return this.neopixelState(!!this.neopixelPin && this.neopixelPin.id); }; this.builtinVisuals["pixels"] = () => new visuals.NeoPixelView(parsePinString); this.builtinPartVisuals["pixels"] = (xy: visuals.Coord) => visuals.mkNeoPixelPart(xy); + + // Initialize LED candles state with the first available pin + const ledCandlesPin = this.edgeConnectorState.getPin(pinList[0]) || this.edgeConnectorState.getPin(getConfig(DAL.CFG_PIN_LED)); + if (ledCandlesPin) { + this.ledCandlesState = new pxsim.LEDCandlesState(ledCandlesPin, 9); // Default to 9 candles + (this as any).ledCandlesState = this.ledCandlesState; // Make it available globally + } } kill() { diff --git a/sim/state/ledcandles.ts b/sim/state/ledcandles.ts index c545c15e..0103a392 100644 --- a/sim/state/ledcandles.ts +++ b/sim/state/ledcandles.ts @@ -2,7 +2,7 @@ console.log("LED Candles state module loaded"); -namespace pxsim { +namespace pxsim.lantern { // Represents the state of an individual candle export interface CandleState { isLit: boolean; @@ -14,16 +14,13 @@ namespace pxsim { export class LEDCandlesState { private candles: CandleState[] = []; private changed = true; - private pin: Pin; private maxCandles: number; - constructor(pin: Pin, maxCandles: number = 9) { - this.pin = pin; + constructor(maxCandles: number = 9) { this.maxCandles = maxCandles; this.initializeCandles(); } - // Initialize all candles to unlit state private initializeCandles() { this.candles = []; for (let i = 0; i < this.maxCandles; i++) { @@ -95,7 +92,17 @@ namespace pxsim { // Register the LED candles state with the runtime export function ledCandlesState(): LEDCandlesState { - return (board() as any).ledCandlesState as LEDCandlesState; + const b = board() as any; + if (!b.ledCandlesState) { + // If not initialized yet, try to get it from the DalBoard instance + if (b && b.board && b.board.ledCandlesState) { + b.ledCandlesState = b.board.ledCandlesState; + } else { + console.warn("LED Candles state not initialized yet"); + return undefined; + } + } + return b.ledCandlesState as LEDCandlesState; } } diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 8dc07b61..b7f0241c 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -268,7 +268,7 @@ namespace pxsim.visuals { updateState() { const opacity = this.pin.mode & PinFlags.Digital ? (this.pin.value > 0 ? 1 : 0) : 0.1 + Math.max(0, Math.min(1023, this.pin.value)) / 1023 * 0.8; - this.ledElement.setAttribute("opacity", opacity.toString()) + this.ledElement.setAttribute("opacity", opacity.toString()); } } @@ -278,7 +278,12 @@ namespace pxsim.visuals { constructor(name: string, x: number, y: number, r: number) { this.name = name; - this.element = svg.elt("circle", { cx: x + r / 2, cy: y + r / 2, r: 10 }) as SVGCircleElement + this.element = svg.elt("circle", { + cx: x + r / 2, + cy: y + r / 2, + r: 10, + class: "sim-candle" + }) as SVGCircleElement; svg.title(this.element, name); } diff --git a/sim/visuals/ledcandles.ts b/sim/visuals/ledcandles.ts index 1e216acf..b5eeabd1 100644 --- a/sim/visuals/ledcandles.ts +++ b/sim/visuals/ledcandles.ts @@ -2,7 +2,7 @@ console.log("LED Candles visuals module loaded"); -namespace pxsim.visuals { +namespace pxsim.lantern { export interface ICandleTheme { candleOn?: string; // Color when candle is lit candleOff?: string; // Color when candle is unlit From da7afb122ca365ff40b35e160c8bcc16f4152d82 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:26:12 -0700 Subject: [PATCH 15/19] removed custom files --- libs/atisa-menorah/lantern.ts | 80 -------------------- sim/state/ledcandles.ts | 114 ---------------------------- sim/visuals/ledcandles.ts | 135 ---------------------------------- 3 files changed, 329 deletions(-) delete mode 100644 libs/atisa-menorah/lantern.ts delete mode 100644 sim/state/ledcandles.ts delete mode 100644 sim/visuals/ledcandles.ts diff --git a/libs/atisa-menorah/lantern.ts b/libs/atisa-menorah/lantern.ts deleted file mode 100644 index e1a09076..00000000 --- a/libs/atisa-menorah/lantern.ts +++ /dev/null @@ -1,80 +0,0 @@ -//% color="#FF5533" icon="\uf06d" weight=90 -namespace lantern { - let strip: light.LightStrip; - - // Initialize the NeoPixel strip if not already done - function initStrip() { - if (!strip) { - // Create a NeoPixel strip with 7 LEDs (one for each candle) - // Using pin P0 as the default data pin for the NeoPixel strip - strip = light.createStrip(pins.D0, 7); - strip.setBrightness(255); - } - return strip; - } - - /** - * Lights up a single candle with the specified color - * @param index which candle to light (0-6) - * @param color RGB color of the candle (e.g., 0xFF0000 for red) - */ - //% block="light candle at $index with color $color" - //% index.min=0 index.max=6 - //% color.shadow="colorNumberPicker" - export function lightCandle(index: number, color: number): void { - const s = initStrip(); - if (index >= 0 && index < s.length()) { - s.setPixelColor(index, color); - s.show(); - } - } - - /** - * Lights up all candles with the specified color - * @param color RGB color for all candles (e.g., 0xFF0000 for red) - */ - //% block="light all candles with color $color" - //% color.shadow="colorNumberPicker" - export function lightAllCandles(color: number): void { - const s = initStrip(); - s.setAll(color); - s.show(); - } - - /** - * Turns off all candles - */ - //% block="clear all candles" - export function clearCandles(): void { - lightAllCandles(0); // 0 means off - } - - /** - * Sets the brightness of the candles - * @param brightness a number between 0 (off) and 255 (full brightness) - */ - //% block="set candle brightness to $brightness" - //% brightness.min=0 brightness.max=255 - export function setBrightness(brightness: number): void { - const s = initStrip(); - s.setBrightness(brightness); - s.show(); - } -} - -// // Include the light namespace for NeoPixel support -// //% block="light" -// namespace light { -// export function createStrip(pin: DigitalPin, numleds: number): NeoPixelStrip { -// // This will be implemented by the NeoPixel extension -// return null; -// } - -// export class NeoPixelStrip { -// public setPixelColor(index: number, rgb: number): void {} -// public setAll(rgb: number): void {} -// public show(): void {} -// public setBrightness(brightness: number): void {} -// public length(): number { return 0; } -// } -// } diff --git a/sim/state/ledcandles.ts b/sim/state/ledcandles.ts deleted file mode 100644 index 0103a392..00000000 --- a/sim/state/ledcandles.ts +++ /dev/null @@ -1,114 +0,0 @@ -/// - -console.log("LED Candles state module loaded"); - -namespace pxsim.lantern { - // Represents the state of an individual candle - export interface CandleState { - isLit: boolean; - brightness: number; - color?: string; // RGB color string (e.g., "#FF0000" for red) - } - - // Manages the state of all LED candles - export class LEDCandlesState { - private candles: CandleState[] = []; - private changed = true; - private maxCandles: number; - - constructor(maxCandles: number = 9) { - this.maxCandles = maxCandles; - this.initializeCandles(); - } - - private initializeCandles() { - this.candles = []; - for (let i = 0; i < this.maxCandles; i++) { - this.candles.push({ - isLit: false, - brightness: 1.0, - color: "#FFA500" // Default to orange (candle color) - }); - } - this.changed = true; - } - - // Set the state of a specific candle - setCandleState(index: number, isLit: boolean, brightness: number = 1.0, color?: string): void { - if (index < 0 || index >= this.maxCandles) return; - - const candle = this.candles[index]; - if (candle.isLit !== isLit || - candle.brightness !== brightness || - (color && candle.color !== color)) { - - candle.isLit = isLit; - candle.brightness = Math.max(0, Math.min(1.0, brightness)); // Clamp between 0 and 1 - if (color) candle.color = color; - this.changed = true; - } - } - - // Toggle a candle's lit state - toggleCandle(index: number): void { - if (index < 0 || index >= this.maxCandles) return; - const candle = this.candles[index]; - this.setCandleState(index, !candle.isLit, candle.brightness, candle.color); - } - - // Set all candles to a specific state - setAllCandles(isLit: boolean, brightness: number = 1.0, color?: string): void { - this.candles.forEach((candle, index) => { - this.setCandleState(index, isLit, brightness, color); - }); - } - - // Get the current state of all candles - getCandleStates(): CandleState[] { - return [...this.candles]; // Return a copy to prevent direct modification - } - - // Get the state of a specific candle - getCandleState(index: number): CandleState | undefined { - if (index < 0 || index >= this.maxCandles) return undefined; - return { ...this.candles[index] }; // Return a copy - } - - // Check if any candle state has changed - hasChanged(): boolean { - return this.changed; - } - - // Clear the changed flag - clearChanged(): void { - this.changed = false; - } - - // Get the number of candles - getCandleCount(): number { - return this.maxCandles; - } - } - - // Register the LED candles state with the runtime - export function ledCandlesState(): LEDCandlesState { - const b = board() as any; - if (!b.ledCandlesState) { - // If not initialized yet, try to get it from the DalBoard instance - if (b && b.board && b.board.ledCandlesState) { - b.ledCandlesState = b.board.ledCandlesState; - } else { - console.warn("LED Candles state not initialized yet"); - return undefined; - } - } - return b.ledCandlesState as LEDCandlesState; - } -} - -// Register the LED candles state with the board -namespace pxsim.board { - export interface CommonBoard { - ledCandlesState: pxsim.LEDCandlesState; - } -} diff --git a/sim/visuals/ledcandles.ts b/sim/visuals/ledcandles.ts deleted file mode 100644 index b5eeabd1..00000000 --- a/sim/visuals/ledcandles.ts +++ /dev/null @@ -1,135 +0,0 @@ -/// - -console.log("LED Candles visuals module loaded"); - -namespace pxsim.lantern { - export interface ICandleTheme { - candleOn?: string; // Color when candle is lit - candleOff?: string; // Color when candle is unlit - } - - export const defaultCandleTheme: ICandleTheme = { - candleOn: "#ff9933", // Orange candle - candleOff: "#4d4d4d", // Dark gray - }; - - export function mkCandlesSvg(xy: Coord, count: number = 7, spacing: number = 30, candleRadius: number = 10): - { el: SVGGElement, candles: SVGGElement[] } { - - const group = svg.elt("g") as SVGGElement; - const candles: SVGGElement[] = []; - - const [x, y] = xy; - - for (let i = 0; i < count; i++) { - // Candle element - using circle for simplicity, can be changed to rect if needed - const candle = svg.elt("circle", { - class: 'sim-candle', - cx: x + i * spacing, - cy: y, - r: candleRadius, - fill: defaultCandleTheme.candleOff - }) as unknown as SVGGElement; - - candles.push(candle); - group.appendChild(candle); - } - - return { el: group, candles }; - } - - export class CandleView { - public element: SVGGElement; - private candles: SVGGElement[] = []; - private theme: ICandleTheme; - private state: pxsim.LEDCandlesState; - private changed = true; - private animationFrame: number; - - constructor() { - this.theme = { ...defaultCandleTheme }; - this.element = svg.elt("g", { class: "sim-candles" }) as SVGGElement; - this.state = pxsim.ledCandlesState(); - this.initialize(); - this.startAnimation(); - } - - private initialize() { - const { el, candles } = mkCandlesSvg( - [0, 0], - this.state.getCandleCount() - ); - - this.candles = candles; - this.element.appendChild(el); - - // Initial update - this.updateState(); - } - - private startAnimation() { - const animate = () => { - if (this.changed || this.state.hasChanged()) { - this.updateState(); - this.changed = false; - this.state.clearChanged(); - } - this.animationFrame = requestAnimationFrame(animate); - }; - this.animationFrame = requestAnimationFrame(animate); - } - - private stopAnimation() { - if (this.animationFrame) { - cancelAnimationFrame(this.animationFrame); - this.animationFrame = undefined; - } - } - - public updateState() { - if (!this.state) return; - - const count = Math.min(this.state.getCandleCount(), this.candles.length); - - for (let i = 0; i < count; i++) { - const candleState = this.state.getCandleState(i); - if (!candleState) continue; - - const { isLit, brightness, color } = candleState; - const baseColor = color || this.theme.candleOn; - - // Update candle - const candle = this.candles[i]; - svg.fill(candle, isLit ? baseColor : this.theme.candleOff); - - // Apply brightness/opacity - candle.style.opacity = isLit ? brightness.toString() : '0'; - } - } - - public updateTheme(theme?: Partial) { - if (theme) { - this.theme = { ...defaultCandleTheme, ...theme }; - this.changed = true; - } - } - - public setPositions(positions: {x: number, y: number}[]) { - positions.forEach((pos, i) => { - if (i < this.candles.length) { - const candle = this.candles[i] as SVGCircleElement; - candle.cx.baseVal.value = pos.x; - candle.cy.baseVal.value = pos.y; - } - }); - this.changed = true; - } - - public dispose() { - this.stopAnimation(); - if (this.element.parentNode) { - this.element.parentNode.removeChild(this.element); - } - } - } -} \ No newline at end of file From 2b54ffd62c388a670d20fd52788026d9ba9a0916 Mon Sep 17 00:00:00 2001 From: Ryan <30853424+totally-not-frito-lays@users.noreply.github.com> Date: Fri, 1 Aug 2025 10:46:07 -0700 Subject: [PATCH 16/19] reset dalboard.ts --- docs/projects.md | 7 +++- docs/projects/SUMMARY.md | 3 +- libs/atisa-menorah/config.ts | 77 ++++++++++++++++-------------------- libs/atisa-menorah/pxt.json | 8 +--- sim/dalboard.ts | 14 +++---- 5 files changed, 48 insertions(+), 61 deletions(-) diff --git a/docs/projects.md b/docs/projects.md index f4356840..801ca101 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -1,3 +1,7 @@ + + + + # Projects ```codecard @@ -52,5 +56,4 @@ [Kwanzaa](/projects/kwanzaa), [My Gallery](/projects/my-gallery), [Adafruit](/boards/adafruit), -[Analog IO](/projects/analog-io) - +[Analog IO](/projects/analog-io) \ No newline at end of file diff --git a/docs/projects/SUMMARY.md b/docs/projects/SUMMARY.md index 4e9d5047..428e18e9 100644 --- a/docs/projects/SUMMARY.md +++ b/docs/projects/SUMMARY.md @@ -1,5 +1,6 @@ -# Projects + +# Projects * [Parole](/projects/parole) * [ex1](/projects/parole/ex1) * [ex2](/projects/parole/ex2) diff --git a/libs/atisa-menorah/config.ts b/libs/atisa-menorah/config.ts index abce0412..e47f2660 100644 --- a/libs/atisa-menorah/config.ts +++ b/libs/atisa-menorah/config.ts @@ -1,45 +1,34 @@ + namespace config { - // Map physical pins to logical pins using PXT core constants - // These map to the definitions in atisa_menorah.h - - // Candle pins - export const CANDLE0 = DAL.CFG_CANDLE0; - export const CANDLE1 = DAL.CFG_CANDLE1; - export const CANDLE2 = DAL.CFG_CANDLE2; - export const CANDLE3 = DAL.CFG_CANDLE3; - export const CANDLE4 = DAL.CFG_CANDLE4; - export const CANDLE5 = DAL.CFG_CANDLE5; - export const CANDLE6 = DAL.CFG_CANDLE6; - - // Power pins - export const VBAT = DAL.CFG_PIN_VBAT; - - // Analog/Digital pins - export const PIN_A0 = DAL.CFG_PIN_A0; - export const PIN_A1 = DAL.CFG_PIN_A1; - export const PIN_A2 = DAL.CFG_PIN_A2; - export const PIN_A3 = DAL.CFG_PIN_A3; - export const PIN_A4 = DAL.CFG_PIN_A4; - - // Digital pins - export const PIN_D0 = DAL.CFG_PIN_D0; - export const PIN_D1 = DAL.CFG_PIN_D1; - export const PIN_D2 = DAL.CFG_PIN_D2; - export const PIN_D3 = DAL.CFG_PIN_D3; - export const PIN_D4 = DAL.CFG_PIN_D4; - - // I2C pins - export const PIN_SDA = DAL.CFG_PIN_SDA; - export const PIN_SCL = DAL.CFG_PIN_SCL; - - // SPI pins - export const PIN_MOSI = DAL.CFG_PIN_MOSI; - export const PIN_MISO = DAL.CFG_PIN_MISO; - export const PIN_SCK = DAL.CFG_PIN_SCK; - - // Built-in LED and Neopixel - export const PIN_LED = DAL.CFG_PIN_LED; - export const PIN_NEOPIXEL = DAL.CFG_PIN_NEOPIXEL; - export const NUM_NEOPIXEL = 1; - // additional pins to look for: SPI, I2C, Flash -} \ No newline at end of file + export const PIN_ONBOARD_DOTSTAR_DATA = DAL.PA00; + export const PIN_ONBOARD_DOTSTAR_CLOCK = DAL.PA01; + export const NUM_ONBOARD_DOTSTARS = 1; + + export const PIN_D0 = DAL.PA08; + export const PIN_D1 = DAL.PA02; + export const PIN_D2 = DAL.PA09; + export const PIN_D3 = DAL.PA07; + export const PIN_D4 = DAL.PA06; + export const PIN_D13 = DAL.PA10; + + export const PIN_A0 = PIN_D1; + export const PIN_A1 = PIN_D2; + export const PIN_A3 = PIN_D3; + export const PIN_A2 = PIN_D4; + export const PIN_A4 = PIN_D0; + + export const PIN_LED = DAL.PA10; + + export const PIN_SDA = PIN_D0; + export const PIN_SCL = PIN_D2; + + export const PIN_SCK = PIN_D3; + export const PIN_MISO = PIN_D2; + export const PIN_MOSI = PIN_D4; + + export const PIN_RX = PIN_D3; + export const PIN_TX = PIN_D4; + + // not supported + export const PIN_JACK_TX = PIN_TX; +} diff --git a/libs/atisa-menorah/pxt.json b/libs/atisa-menorah/pxt.json index 6f955b26..a89c2611 100644 --- a/libs/atisa-menorah/pxt.json +++ b/libs/atisa-menorah/pxt.json @@ -5,14 +5,9 @@ "README.md", "device.d.ts", "config.ts", - "lantern.ts", "board.json", "board.svg" ], - "additionalFilePath": "./include", - "include": [ - "atisa_menorah.h" - ], "core": true, "dalDTS": { "includeDirs": [ @@ -45,8 +40,7 @@ "touchd1", "light", "jacdac", - "music", - "lantern" + "music" ], "simulator": { "runtime": { diff --git a/sim/dalboard.ts b/sim/dalboard.ts index c3c55ee3..d627fd8b 100644 --- a/sim/dalboard.ts +++ b/sim/dalboard.ts @@ -50,7 +50,7 @@ namespace pxsim { lcdState: LCDState; radioState: RadioState; controlMessageState: ControlMessageState; - ledCandlesState: any; // Will be of type LEDCandlesState + // ledCandlesState: any; // Will be of type LEDCandlesState constructor(public boardDefinition: BoardDefinition) { super(); @@ -179,12 +179,12 @@ namespace pxsim { this.builtinVisuals["pixels"] = () => new visuals.NeoPixelView(parsePinString); this.builtinPartVisuals["pixels"] = (xy: visuals.Coord) => visuals.mkNeoPixelPart(xy); - // Initialize LED candles state with the first available pin - const ledCandlesPin = this.edgeConnectorState.getPin(pinList[0]) || this.edgeConnectorState.getPin(getConfig(DAL.CFG_PIN_LED)); - if (ledCandlesPin) { - this.ledCandlesState = new pxsim.LEDCandlesState(ledCandlesPin, 9); // Default to 9 candles - (this as any).ledCandlesState = this.ledCandlesState; // Make it available globally - } + // // Initialize LED candles state with the first available pin + // const ledCandlesPin = this.edgeConnectorState.getPin(pinList[0]) || this.edgeConnectorState.getPin(getConfig(DAL.CFG_PIN_LED)); + // if (ledCandlesPin) { + // this.ledCandlesState = new pxsim.LEDCandlesState(ledCandlesPin, 9); // Default to 9 candles + // (this as any).ledCandlesState = this.ledCandlesState; // Make it available globally + // } } kill() { From b48a80d5b3a31eb5750c3a74dfde1021c91aea4e Mon Sep 17 00:00:00 2001 From: Angelina Mkrtychyan Date: Mon, 4 Aug 2025 14:39:13 -0700 Subject: [PATCH 17/19] first round of attempted fixes --- libs/atisa-menorah/board.json | 166 +- libs/atisa-menorah/board.svg | 1800 ++++++++++----- libs/atisa-menorah/boardhd.svg | 3812 ++++++++++++++++++++------------ libs/atisa-menorah/config.ts | 73 +- package.json | 1 + 5 files changed, 3759 insertions(+), 2093 deletions(-) diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 783dac7b..9c2eb146 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -3,118 +3,69 @@ "visual": { "image": "pkg://board.svg", "useCrocClips": false, - "width": 409.6239929199219, - "height": 485.5690002441406, + "width": 409.62432861328125, + "height": 485.56903076171875, "pinDist": 15, "pinBlocks": [ { - "x": 10.85988863653548, - "y": 3.141045080908931, - "labels": [ - "CANDLE0" - ] - }, - { - "x": 67.06181081486271, - "y": 3.141045080908931, - "labels": [ - "CANDLE1" - ] - }, - { - "x": 121.4207186561824, - "y": 3.141045080908931, - "labels": [ - "CANDLE2" - ] - }, - { - "x": 193.1495027572595, - "y": 3.141045080908931, - "labels": [ - "CANDLE3" - ] - }, - { - "x": 262.04441259686496, - "y": 3.141045080908931, - "labels": [ - "CANDLE4" - ] - }, - { - "x": 320.7433152108822, - "y": 3.141045080908931, - "labels": [ - "CANDLE5" - ] - }, - { - "x": 372.9421273706446, - "y": 2.923037400420722, - "labels": [ - "CANDLE6" - ] - }, - { - "x": 227.75053162155578, - "y": 369.6883747857013, + "x": 229.57081643852595, + "y": 371.52201865094, "labels": [ "VBAT" ] }, { - "x": 208.02239858132688, - "y": 369.6883747857013, + "x": 209.8342452256634, + "y": 371.52201865094, "labels": [ "GND" ] }, { - "x": 188.26454681925023, - "y": 369.6883747857013, + "x": 190.09771973947792, + "y": 371.52201865094, "labels": [ "A4_D4_TX_MOSI" ] }, { - "x": 168.5363956357235, - "y": 369.6883747857013, + "x": 170.36112566327685, + "y": 371.52201865094, "labels": [ "A3_D3_RX_SCK" ] }, { - "x": 148.79833821158084, - "y": 468.1893829606932, + "x": 150.62453158707578, + "y": 470.00808139975123, "labels": [ "3V3" ] }, { - "x": 168.5363956357235, - "y": 468.1893829606932, + "x": 170.36112566327685, + "y": 470.00808139975123, "labels": [ "A1_D2_SCL_MISO" ] }, { - "x": 188.26454681925023, - "y": 468.1893829606932, + "x": 190.09771973947792, + "y": 470.00808139975123, "labels": [ "A0_D1" ] }, { - "x": 208.02239858132688, - "y": 468.1893829606932, + "x": 209.8342452256634, + "y": 470.00808139975123, "labels": [ "A2_D0_SDA" ] }, { - "x": 114.92062820192746, - "y": 412.6419839288162, + "x": 114.94014157857497, + "y": 412.65286062400634, "labels": [ "RESET" ] @@ -122,33 +73,74 @@ ], "leds": [ { - "x": 282.4364270480412, - "y": 466.1283975684879, - "w": 6.272183418546294, - "h": 6.272120519638412, + "x": 10.888779289887584, + "y": 3.2486253703601675, + "w": 22.824869530364285, + "h": 22.824996740758806, "color": "#ff0000", - "label": "LED" + "label": "LED0" + }, + { + "x": 67.12416692456887, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED1" + }, + { + "x": 121.49096819649579, + "y": 3.2486253703601675, + "w": 22.824878104116234, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED2" + }, + { + "x": 193.2207603288292, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED3" + }, + { + "x": 262.1248953160241, + "y": 3.2486253703601675, + "w": 22.824895251620127, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED4" + }, + { + "x": 320.8342447909616, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED5" + }, + { + "x": 372.9680981057083, + "y": 3.0010710997843644, + "w": 22.824895251620127, + "h": 22.824996740758806, + "color": "#ff0000", + "label": "LED6" }, { - "x": 189.1166830884958, - "y": 405.527632755068, - "w": 11.147242187588585, - "h": 10.057191785158693, - "color": "neopixel", - "label": "NEOPIXEL" + "x": 282.4832350201119, + "y": 466.177443421515, + "w": 6.216999012096948, + "h": 6.21703599676494, + "color": "#ff0000", + "label": "LED" } ], "touchPads": [], "buttons": [] }, "gpioPinMap": { - "CANDLE0": "CANDLE0", - "CANDLE1": "CANDLE1", - "CANDLE2": "CANDLE2", - "CANDLE3": "CANDLE3", - "CANDLE4": "CANDLE4", - "CANDLE5": "CANDLE5", - "CANDLE6": "CANDLE6", "VBAT": "VBAT", "GND": "GND", "A4_D4_TX_MOSI": "A4_D4_TX_MOSI", diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index 9a25cb06..ce419c2c 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -1,682 +1,1394 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + - - - - + + + + + + + + - - - - + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + - - - - + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg index f19fd5e3..020fd59f 100644 --- a/libs/atisa-menorah/boardhd.svg +++ b/libs/atisa-menorah/boardhd.svg @@ -2,1447 +2,2385 @@ - - - - - - - - - - - - -element:BATpackage:JSTPH2element:CN1package:4UCONN_20329_V2element:IC3package:QFN32_5MMelement:JP3package:1X05_ROUND_76element:JP4package:1X05_ROUND_76element:Lpackage:CHIPLED_0603_NOOUTLINEpolygonelement:PWRpackage:CHIPLED_0603_NOOUTLINEpolygonelement:Q2package:BTN_KMR2_4.6X2.8element:SWCpackage:B1,27element:SWDpackage:B1,27element:U$1package:TRINKET_M0_BOTTOMelement:U$6package:FIDUCIAL_1MMelement:U$8package:MOUNTINGHOLE_2.0_PLATEDelement:U$9package:MOUNTINGHOLE_2.0_PLATEDelement:U$12package:PCBFEAT-REV-040element:U$20package:TRINKET_M0_TOPimage/svg+xml + xmlns:dc="http://purl.org/dc/elements/1.1/"> boardhd.svg element:BAT package:JSTPH2 element:CN1 package:4UCONN_20329_V2 element:IC3 package:QFN32_5MM element:JP3 package:1X05_ROUND_76 element:JP4 package:1X05_ROUND_76 element:L package:CHIPLED_0603_NOOUTLINE polygon element:PWR package:CHIPLED_0603_NOOUTLINE polygon element:Q2 package:BTN_KMR2_4.6X2.8 element:SWC package:B1,27 element:SWD package:B1,27 element:U$1 package:TRINKET_M0_BOTTOM element:U$6 package:FIDUCIAL_1MM element:U$8 package:MOUNTINGHOLE_2.0_PLATED element:U$9 package:MOUNTINGHOLE_2.0_PLATED element:U$12 package:PCBFEAT-REV-040 element:U$20 package:TRINKET_M0_TOP image/svg+xml diff --git a/libs/atisa-menorah/config.ts b/libs/atisa-menorah/config.ts index e47f2660..6a03cb42 100644 --- a/libs/atisa-menorah/config.ts +++ b/libs/atisa-menorah/config.ts @@ -1,34 +1,57 @@ - namespace config { - export const PIN_ONBOARD_DOTSTAR_DATA = DAL.PA00; - export const PIN_ONBOARD_DOTSTAR_CLOCK = DAL.PA01; - export const NUM_ONBOARD_DOTSTARS = 1; - - export const PIN_D0 = DAL.PA08; - export const PIN_D1 = DAL.PA02; - export const PIN_D2 = DAL.PA09; - export const PIN_D3 = DAL.PA07; - export const PIN_D4 = DAL.PA06; + // Pins based on Trinket M0 layout + export const PIN_NEOPIXEL = DAL.PA02; // D1 controls all Menorah LEDs + + // Other optional pins (define as needed) + export const PIN_A0 = DAL.PA02; + export const PIN_A1 = DAL.PA09; + export const PIN_A2 = DAL.PA08; + export const PIN_A4 = DAL.PA06; export const PIN_D13 = DAL.PA10; - export const PIN_A0 = PIN_D1; - export const PIN_A1 = PIN_D2; - export const PIN_A3 = PIN_D3; - export const PIN_A2 = PIN_D4; - export const PIN_A4 = PIN_D0; + // If using buttons or other parts: + export const PIN_BUTTON_A = DAL.PA07; // Optional, for a button on D3 for example + + // Simulator configuration + export const BOARD_NAME = "Menorah Trinket"; + export const BOARD_ID = "menorah-trinket-v1"; + export const PIN_DISPLAY_NAME = "menorah"; + export const NUM_NEOPIXELS = 7; // Or however many LEDs your Menorah has + +} - export const PIN_LED = DAL.PA10; - export const PIN_SDA = PIN_D0; - export const PIN_SCL = PIN_D2; - export const PIN_SCK = PIN_D3; - export const PIN_MISO = PIN_D2; - export const PIN_MOSI = PIN_D4; - export const PIN_RX = PIN_D3; - export const PIN_TX = PIN_D4; +/* - // not supported - export const PIN_JACK_TX = PIN_TX; +namespace config { + export const PIN_A0 = DAL.PA02; + export const PIN_D1 = DAL.PA05; + export const PIN_D2 = DAL.PA06; + export const PIN_D3 = DAL.PA09; + export const PIN_D4 = DAL.PA08; + + export const PIN_SCL = DAL.PA09; + export const PIN_SDA = DAL.PA08; + export const PIN_RX = DAL.PA09; + export const PIN_TX = DAL.PA08; + export const PIN_MISO = DAL.PA06; + export const PIN_MOSI = DAL.PA05; + export const PIN_SCK = DAL.PA09; + + export const PIN_LED0 = DAL.PA05; + export const PIN_LED1 = DAL.PA06; + export const PIN_LED2 = DAL.PA08; + export const PIN_LED3 = DAL.PA09; + export const PIN_LED4 = DAL.PA02; + export const PIN_LED5 = DAL.PA04; + export const PIN_LED6 = DAL.PA07; + export const PIN_LED = DAL.PA02; + + export const PIN_NEOPIXEL = DAL.PA01; + export const NUM_NEOPIXEL = 1; } + + +*/ \ No newline at end of file diff --git a/package.json b/package.json index 14403ba7..3db031aa 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@types/marked": "^0.3.0", "@types/node": "^9.3.0", "@types/web-bluetooth": "0.0.4", + "glob-exec": "^0.1.1", "semantic-ui-less": "2.4.1", "typescript": "4.8.3" }, From 810c934ea50af21463b1b8ac817173b6a26de6cc Mon Sep 17 00:00:00 2001 From: Angelina Mkrtychyan Date: Wed, 27 Aug 2025 16:06:06 -0700 Subject: [PATCH 18/19] this is the first working copy of the LEDs in the sim. I have some extra files I will remove later but I want to save this version. In future, delete the extra board.json and config.ts, also delete the ledcandles file. After, need to finish cleaning up the working board.json and config.ts --- libs/atisa-menorah/1board.json | 205 +++++++++++ libs/atisa-menorah/1config.ts | 98 ++++++ libs/atisa-menorah/2board.svg | 606 +++++++++++++++++++++++++++++++++ libs/atisa-menorah/board.json | 350 ++++++++++++++----- libs/atisa-menorah/board.svg | 14 +- libs/atisa-menorah/boardhd.svg | 21 +- libs/atisa-menorah/config.ts | 106 +++--- sim/visuals/ledcandles.ts | 59 ++++ 8 files changed, 1297 insertions(+), 162 deletions(-) create mode 100644 libs/atisa-menorah/1board.json create mode 100644 libs/atisa-menorah/1config.ts create mode 100644 libs/atisa-menorah/2board.svg create mode 100644 sim/visuals/ledcandles.ts diff --git a/libs/atisa-menorah/1board.json b/libs/atisa-menorah/1board.json new file mode 100644 index 00000000..76a694a0 --- /dev/null +++ b/libs/atisa-menorah/1board.json @@ -0,0 +1,205 @@ +{ + "driveDisplayName": "", + "visual": { + "image": "pkg://board.svg", + "useCrocClips": true, + "width": 409.62432861328125, + "height": 485.56903076171875, + "pinDist": 15, + "pinBlocks": [ + { + "x": 229.57081643852595, + "y": 371.52201865094, + "labels": [ + "VBAT" + ] + }, + { + "x": 209.8342452256634, + "y": 371.52201865094, + "labels": [ + "GND" + ] + }, + { + "x": 190.09771973947792, + "y": 371.52201865094, + "labels": [ + "A4_D4_TX_MOSI" + ] + }, + { + "x": 170.36112566327685, + "y": 371.52201865094, + "labels": [ + "A3_D3_RX_SCK" + ] + }, + { + "x": 150.62453158707578, + "y": 470.00808139975123, + "labels": [ + "3V3" + ] + }, + { + "x": 170.36112566327685, + "y": 470.00808139975123, + "labels": [ + "A1_D2_SCL_MISO" + ] + }, + { + "x": 190.09771973947792, + "y": 470.00808139975123, + "labels": [ + "A0_D1" + ] + }, + { + "x": 209.8342452256634, + "y": 470.00808139975123, + "labels": [ + "A2_D0_SDA" + ] + }, + { + "x": 114.94014157857497, + "y": 412.65286062400634, + "labels": [ + "RESET" + ] + } + ], + "leds": [ + { + "x": 10.888779289887584, + "y": 3.2486253703601675, + "w": 22.824869530364285, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL0" + }, + { + "x": 67.12416692456887, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL1" + }, + { + "x": 121.49096819649579, + "y": 3.2486253703601675, + "w": 22.824878104116234, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL2" + }, + { + "x": 193.2207603288292, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL3" + }, + { + "x": 262.1248953160241, + "y": 3.2486253703601675, + "w": 22.824895251620127, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL4" + }, + { + "x": 320.8342447909616, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL5" + }, + { + "x": 372.9680981057083, + "y": 3.0010710997843644, + "w": 22.824895251620127, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL6" + }, + { + "x": 282.4832350201119, + "y": 466.177443421515, + "w": 6.216999012096948, + "h": 6.21703599676494, + "color": "#ff0000", + "label": "LED" + } + ], + "touchPads": [], + "buttons": [] + }, + "gpioPinMap": { + "VBAT": "VBAT", + "GND": "GND", + "A4_D4_TX_MOSI": "A4_D4_TX_MOSI", + "A4": "A4_D4_TX_MOSI", + "D4": "A4_D4_TX_MOSI", + "TX": "A4_D4_TX_MOSI", + "MOSI": "A4_D4_TX_MOSI", + "A3_D3_RX_SCK": "A3_D3_RX_SCK", + "A3": "A3_D3_RX_SCK", + "D3": "A3_D3_RX_SCK", + "RX": "A3_D3_RX_SCK", + "SCK": "A3_D3_RX_SCK", + "3V3": "3V3", + "A1_D2_SCL_MISO": "A1_D2_SCL_MISO", + "A1": "A1_D2_SCL_MISO", + "D2": "A1_D2_SCL_MISO", + "SCL": "A1_D2_SCL_MISO", + "MISO": "A1_D2_SCL_MISO", + "A0_D1": "A0_D1", + "A0": "A0_D1", + "D1": "A0_D1", + "A2_D0_SDA": "A2_D0_SDA", + "A2": "A2_D0_SDA", + "D0": "A2_D0_SDA", + "SDA": "A2_D0_SDA", + "LED": "LED", + "RESET": "RESET", + "NEOPIXEL0": "NEOPIXEL0", + "NEOPIXEL1": "NEOPIXEL1", + "NEOPIXEL2": "NEOPIXEL2", + "NEOPIXEL3": "NEOPIXEL3", + "NEOPIXEL4": "NEOPIXEL4", + "NEOPIXEL5": "NEOPIXEL5", + "NEOPIXEL6": "NEOPIXEL6", + "NEOPIXEL": "NEOPIXEL" + }, + "groundPins": [ + "GND" + ], + "threeVoltPins": [ + "3V3" + ], + "fiveVoltPins": [], + "i2cPins": { + "SDA": "SDA", + "SCL": "SCL" + }, + "onboardComponents": [ + "pixel" + ], + "marginWhenBreadboarding": [ + 0, + 0, + 80, + 0 + ], + "spiPins": { + "MOSI": "MOSI", + "MISO": "MISO", + "SCK": "SCK" + } +} \ No newline at end of file diff --git a/libs/atisa-menorah/1config.ts b/libs/atisa-menorah/1config.ts new file mode 100644 index 00000000..9f33d30b --- /dev/null +++ b/libs/atisa-menorah/1config.ts @@ -0,0 +1,98 @@ +namespace config { + export const PIN_NEOPIXEL = DAL.PB23; + export const NUM_NEOPIXELS = 7; + + export const PIN_ONBOARD_DOTSTAR_DATA = DAL.PA00; + export const PIN_ONBOARD_DOTSTAR_CLOCK = DAL.PA01; + export const NUM_ONBOARD_DOTSTARS = 1; + + export const PIN_D0 = DAL.PA08; + export const PIN_D1 = DAL.PA02; + export const PIN_D2 = DAL.PA09; + export const PIN_D3 = DAL.PA07; + export const PIN_D4 = DAL.PA06; + export const PIN_D13 = DAL.PA10; + + export const PIN_A0 = PIN_D1; + export const PIN_A1 = PIN_D2; + export const PIN_A3 = PIN_D3; + export const PIN_A2 = PIN_D4; + export const PIN_A4 = PIN_D0; + + export const PIN_LED = DAL.PA10; + + export const PIN_SDA = PIN_D0; + export const PIN_SCL = PIN_D2; + + export const PIN_SCK = PIN_D3; + export const PIN_MISO = PIN_D2; + export const PIN_MOSI = PIN_D4; + + export const PIN_RX = PIN_D3; + export const PIN_TX = PIN_D4; + + // not supported + export const PIN_JACK_TX = PIN_TX; +} + + + + + +// namespace config { +// // Pins based on Trinket M0 layout +// export const PIN_NEOPIXEL = DAL.PA02; // D1 controls all Menorah LEDs + +// // Other optional pins (define as needed) +// export const PIN_A0 = DAL.PA02; +// export const PIN_A1 = DAL.PA09; +// export const PIN_A2 = DAL.PA08; +// export const PIN_A4 = DAL.PA06; +// export const PIN_D13 = DAL.PA10; + +// // If using buttons or other parts: +// export const PIN_BUTTON_A = DAL.PA07; // Optional, for a button on D3 for example + +// // Simulator configuration +// export const BOARD_NAME = "Menorah Trinket"; +// export const BOARD_ID = "menorah-trinket-v1"; +// export const PIN_DISPLAY_NAME = "menorah"; +// export const NUM_NEOPIXELS = 7; // Or however many LEDs your Menorah has + +// } + + + + +/* + +namespace config { + export const PIN_A0 = DAL.PA02; + export const PIN_D1 = DAL.PA05; + export const PIN_D2 = DAL.PA06; + export const PIN_D3 = DAL.PA09; + export const PIN_D4 = DAL.PA08; + + export const PIN_SCL = DAL.PA09; + export const PIN_SDA = DAL.PA08; + export const PIN_RX = DAL.PA09; + export const PIN_TX = DAL.PA08; + export const PIN_MISO = DAL.PA06; + export const PIN_MOSI = DAL.PA05; + export const PIN_SCK = DAL.PA09; + + export const PIN_LED0 = DAL.PA05; + export const PIN_LED1 = DAL.PA06; + export const PIN_LED2 = DAL.PA08; + export const PIN_LED3 = DAL.PA09; + export const PIN_LED4 = DAL.PA02; + export const PIN_LED5 = DAL.PA04; + export const PIN_LED6 = DAL.PA07; + export const PIN_LED = DAL.PA02; + + export const PIN_NEOPIXEL = DAL.PA01; + export const NUM_NEOPIXEL = 1; +} + + +*/ \ No newline at end of file diff --git a/libs/atisa-menorah/2board.svg b/libs/atisa-menorah/2board.svg new file mode 100644 index 00000000..4a354568 --- /dev/null +++ b/libs/atisa-menorah/2board.svg @@ -0,0 +1,606 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AB + + + + + diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index 9c2eb146..ba4edb68 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -2,197 +2,359 @@ "driveDisplayName": "", "visual": { "image": "pkg://board.svg", - "useCrocClips": false, + "useCrocClips": true, "width": 409.62432861328125, "height": 485.56903076171875, "pinDist": 15, "pinBlocks": [ { - "x": 229.57081643852595, - "y": 371.52201865094, + "x": 124.92086316385772, + "y": 159.93345053018618, "labels": [ - "VBAT" + "BTN_SLIDE" ] }, { - "x": 209.8342452256634, - "y": 371.52201865094, + "x": 59.92256441197212, + "y": 17.840147426658344, "labels": [ - "GND" + "GND3" ] }, { - "x": 190.09771973947792, - "y": 371.52201865094, + "x": 29.531498322529206, + "y": 43.30532833521745, "labels": [ - "A4_D4_TX_MOSI" + "A4" ] }, { - "x": 170.36112566327685, - "y": 371.52201865094, + "x": 9.883948075867105, + "y": 77.52829833274161, "labels": [ - "A3_D3_RX_SCK" + "A5_SDA" ] }, { - "x": 150.62453158707578, - "y": 470.00808139975123, + "x": 3.1209888410522737, + "y": 116.47365044798116, "labels": [ "3V3" ] }, { - "x": 170.36112566327685, - "y": 470.00808139975123, + "x": 10.233754808752911, + "y": 156.52681276894702, + "labels": [ + "A6_RX" + ] + }, + { + "x": 30.872421806669653, + "y": 190.98294134989393, + "labels": [ + "A7_RX" + ] + }, + { + "x": 60.19798855815587, + "y": 215.3529800753301, + "labels": [ + "GND" + ] + }, + { + "x": 173.768981421397, + "y": 215.3529800753301, + "labels": [ + "VOUT" + ] + }, + { + "x": 204.49378208019186, + "y": 189.93353240255723, + "labels": [ + "A0" + ] + }, + { + "x": 224.25791131859782, + "y": 155.30247907777633, "labels": [ - "A1_D2_SCL_MISO" + "A1" ] }, { - "x": 190.09771973947792, - "y": 470.00808139975123, + "x": 231.0208879928262, + "y": 116.41538870525896, "labels": [ - "A0_D1" + "GND2" ] }, { - "x": 209.8342452256634, - "y": 470.00808139975123, + "x": 224.25791131859782, + "y": 77.35337358890759, "labels": [ - "A2_D0_SDA" + "A2" ] }, { - "x": 114.94014157857497, - "y": 412.65286062400634, + "x": 204.49378208019186, + "y": 43.013796396538574, "labels": [ - "RESET" + "A3" + ] + }, + { + "x": 173.82728486879978, + "y": 17.477769432054345, + "labels": [ + "3V32" ] } ], "leds": [ + { + "x": 143.64726358645467, + "y": 117.87656419347279, + "w": 7.491260535887221, + "h": 10.307417510334698, + "color": "#ff0000", + "label": "IRRXLED" + }, + { + "x": 98.69974222572388, + "y": 117.87656419347279, + "w": 7.491274487418067, + "h": 10.307417510334698, + "color": "#ff0000", + "label": "IRTXLED" + }, + { + "x": 152.43907187621588, + "y": 12.582555305516507, + "w": 6.1438774929653714, + "h": 6.143907253243276, + "color": "#ff0000", + "label": "LED" + }, + { + "x": 372.9680981057083, + "y": 3.0010710997843644, + "w": 22.824895251620127, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL6" + }, + { + "x": 320.8342447909616, + "y": 3.2486253703601675, + "w": 22.824860956612337, + "h": 22.824996740758806, + "color": "neopixel", + "label": "NEOPIXEL5" + }, { "x": 10.888779289887584, "y": 3.2486253703601675, "w": 22.824869530364285, "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED0" + "color": "neopixel", + "label": "NEOPIXEL0" }, { "x": 67.12416692456887, "y": 3.2486253703601675, "w": 22.824860956612337, "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED1" + "color": "neopixel", + "label": "NEOPIXEL1" }, { "x": 121.49096819649579, "y": 3.2486253703601675, "w": 22.824878104116234, "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED2" + "color": "neopixel", + "label": "NEOPIXEL2" }, { "x": 193.2207603288292, "y": 3.2486253703601675, "w": 22.824860956612337, "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED3" + "color": "neopixel", + "label": "NEOPIXEL3" }, { "x": 262.1248953160241, "y": 3.2486253703601675, "w": 22.824895251620127, "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED4" + "color": "neopixel", + "label": "NEOPIXEL4" + } + ], + "touchPads": [ + { + "x": 29.531498322529206, + "y": 43.30532833521745, + "w": 15.679958098734177, + "h": 15.679998444579105, + "label": "A4" }, { - "x": 320.8342447909616, - "y": 3.2486253703601675, - "w": 22.824860956612337, - "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED5" + "x": 9.883948075867105, + "y": 77.52829833274161, + "w": 15.679958098734177, + "h": 15.679970541445616, + "label": "A5" }, { - "x": 372.9680981057083, - "y": 3.0010710997843644, - "w": 22.824895251620127, - "h": 22.824996740758806, - "color": "#ff0000", - "label": "LED6" + "x": 10.233754808752911, + "y": 156.52681276894702, + "w": 15.679958098734177, + "h": 15.679970541445616, + "label": "A6" }, { - "x": 282.4832350201119, - "y": 466.177443421515, - "w": 6.216999012096948, - "h": 6.21703599676494, - "color": "#ff0000", - "label": "LED" + "x": 30.872421806669653, + "y": 190.98294134989393, + "w": 15.679958098734177, + "h": 15.680026347712593, + "label": "A7" + }, + { + "x": 224.25791131859782, + "y": 155.30247907777633, + "w": 15.679958098734177, + "h": 15.679998444579105, + "label": "A1" + }, + { + "x": 224.25791131859782, + "y": 77.35337358890759, + "w": 15.679958098734177, + "h": 15.679998444579105, + "label": "A2" + }, + { + "x": 204.49378208019186, + "y": 43.013796396538574, + "w": 15.679958098734177, + "h": 15.679998444579105, + "label": "A3" } ], - "touchPads": [], - "buttons": [] + "buttons": [ + { + "x": 68.85266027547256, + "y": 111.9112648976839, + "w": 14.746670442833569, + "h": 14.746694435684478, + "index": 0 + }, + { + "x": 166.23893562975968, + "y": 111.9112648976839, + "w": 14.748414384189239, + "h": 14.746694435684478, + "index": 1 + }, + { + "x": 147.13927595092585, + "y": 140.0295873507819, + "w": 14.746670442833569, + "h": 14.746694435684478, + "index": 2 + } + ], + "reset": { + "x": 120.62033168383603, + "y": 108.7413573209539, + "w": 8.601062960043372, + "h": 8.601085091298456 + } }, "gpioPinMap": { - "VBAT": "VBAT", - "GND": "GND", - "A4_D4_TX_MOSI": "A4_D4_TX_MOSI", - "A4": "A4_D4_TX_MOSI", - "D4": "A4_D4_TX_MOSI", - "TX": "A4_D4_TX_MOSI", - "MOSI": "A4_D4_TX_MOSI", - "A3_D3_RX_SCK": "A3_D3_RX_SCK", - "A3": "A3_D3_RX_SCK", - "D3": "A3_D3_RX_SCK", - "RX": "A3_D3_RX_SCK", - "SCK": "A3_D3_RX_SCK", - "3V3": "3V3", - "A1_D2_SCL_MISO": "A1_D2_SCL_MISO", - "A1": "A1_D2_SCL_MISO", - "D2": "A1_D2_SCL_MISO", - "SCL": "A1_D2_SCL_MISO", - "MISO": "A1_D2_SCL_MISO", - "A0_D1": "A0_D1", - "A0": "A0_D1", - "D1": "A0_D1", - "A2_D0_SDA": "A2_D0_SDA", - "A2": "A2_D0_SDA", - "D0": "A2_D0_SDA", - "SDA": "A2_D0_SDA", + "THERMOMETER": "THERMOMETER", + "LIGHTSENSOR": "LIGHTSENSOR", + "MICROPHONE": "MICROPHONE", + "IRRXLED": "IRRXLED", + "IRTXLED": "IRTXLED", + "ACCELEROMETER": "ACCELEROMETER", "LED": "LED", - "RESET": "RESET", - "NEOPIXEL": "NEOPIXEL" + "NEOPIXEL6": "NEOPIXEL6", + "NEOPIXEL5": "NEOPIXEL5", + "NEOPIXEL7": "NEOPIXEL7", + "NEOPIXEL8": "NEOPIXEL8", + "NEOPIXEL9": "NEOPIXEL9", + "NEOPIXEL0": "NEOPIXEL0", + "NEOPIXEL1": "NEOPIXEL1", + "NEOPIXEL2": "NEOPIXEL2", + "NEOPIXEL3": "NEOPIXEL3", + "NEOPIXEL4": "NEOPIXEL4", + "RESETBTN": "RESETBTN", + "HEADPHONE": "HEADPHONE", + "BTN_A": "BTN_A", + "BTN": "BTN_AB", + "A": "BTN_A", + "BTN_B": "BTN_B", + "B": "BTN_B", + "BTN_SLIDE": "BTN_SLIDE", + "SLIDE": "BTN_SLIDE", + "GND3": "GND3", + "A4": "A4", + "A5_SDA": "A5_SDA", + "A5": "A5_SDA", + "SDA": "A5_SDA", + "3V3": "3V3", + "A6_RX": "A6_RX", + "A6": "A6_RX", + "RX": "A7_RX", + "A7_RX": "A7_RX", + "A7": "A7_RX", + "JACK_TX": "A7_RX", + "GND": "GND", + "VOUT": "VOUT", + "A0": "A0", + "A1": "A1", + "GND2": "GND2", + "A2": "A2", + "A3": "A3", + "3V32": "3V32", + "BTN_AB": "BTN_AB", + "AB": "BTN_AB" }, "groundPins": [ - "GND" + "GND3", + "GND", + "GND2" ], "threeVoltPins": [ - "3V3" + "3V3", + "VOUT", + "3V32" ], - "fiveVoltPins": [], "i2cPins": { "SDA": "SDA", "SCL": "SCL" }, "onboardComponents": [ - "pixel" + "thermometer", + "lightsensor", + "microphone", + "accelerometer", + "neopixel", + "pixels", + "headphone", + "switch", + "ir" ], "marginWhenBreadboarding": [ 0, 0, 80, 0 - ], - "spiPins": { - "MOSI": "MOSI", - "MISO": "MISO", - "SCK": "SCK" - } + ] } \ No newline at end of file diff --git a/libs/atisa-menorah/board.svg b/libs/atisa-menorah/board.svg index ce419c2c..dca88b06 100644 --- a/libs/atisa-menorah/board.svg +++ b/libs/atisa-menorah/board.svg @@ -7,13 +7,13 @@ - - - - - - - + + + + + + + diff --git a/libs/atisa-menorah/boardhd.svg b/libs/atisa-menorah/boardhd.svg index 020fd59f..caaeed90 100644 --- a/libs/atisa-menorah/boardhd.svg +++ b/libs/atisa-menorah/boardhd.svg @@ -68,7 +68,8 @@ fill="#fecd00" fill-opacity="1" gorn="0.2.0.0.0.1.0" - id="LED0" + id="NEOPIXEL0" + data-id="LED0" r="11.412503" style="stroke-width:6.51027" /> { + // required by IBoardPart + public element: SVGElement; + public defs: SVGElement[] = []; + public style: string = ""; // we can define CSS styles here if needed + + private state: CommonNeoPixelState; // holds the neopixel data (a buffer of rgb values) + private bus: EventBus; // lets you hook into simulator events + private leds: SVGElement[] = []; // array of SVG elements for the LEDs + + public init(bus: EventBus, state: CommonNeoPixelState, svgEl: SVGSVGElement, otherParams: Map) { + this.bus = bus; + this.state = state; + + // Top-level SVG group for the part + this.element = svg.elt("g"); + + // Grab the LED elements from the SVG board by their data-id + //* need to test this with print statements + for (let i = 0; i < NUM_LEDS; ++i) { + console.log(`LED${i}`); // instead print it out to another file so its not hard to find + const el = svgEl.querySelector(`[data-id="LED${i}"]`) as SVGElement; + if (el) { + this.leds.push(el); + el.setAttribute("fill", "#222"); // Start off (dark) + } + } + + this.updateState(); + } + + public updateState() { + if (!this.state?.buffer) return; + + const stride = 3; // RGB mode + for (let i = 0; i < this.leds.length; ++i) { + const base = i * stride; + if (base + 2 >= this.state.buffer.length) continue; + + const r = this.state.buffer[base]; + const g = this.state.buffer[base + 1]; + const b = this.state.buffer[base + 2]; + const hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`; + this.leds[i].setAttribute("fill", hex); + } + } + + public moveToCoord(xy: Coord) { + // dont need, fixed position via SVG + } + + public updateTheme() { + // dont need, optional theming + } + } +} From 98434bc3543ea22d304d74280d80277edcd37ef5 Mon Sep 17 00:00:00 2001 From: Angelina Mkrtychyan Date: Sat, 20 Sep 2025 20:49:22 -0700 Subject: [PATCH 19/19] first attempt at adding a highlight overlay --- libs/atisa-menorah/board.json | 42 +------------- libs/atisa-menorah/pxt.json | 2 +- libs/atisa-menorah/sim/highlight-corner.ts | 63 +++++++++++++++++++++ libs/atisa-menorah/sim/menorah-sim-patch.ts | 32 +++++++++++ libs/atisa-menorah/sim/visual.ts | 31 ++++++++++ 5 files changed, 130 insertions(+), 40 deletions(-) create mode 100644 libs/atisa-menorah/sim/highlight-corner.ts create mode 100644 libs/atisa-menorah/sim/menorah-sim-patch.ts create mode 100644 libs/atisa-menorah/sim/visual.ts diff --git a/libs/atisa-menorah/board.json b/libs/atisa-menorah/board.json index ba4edb68..9b09410d 100644 --- a/libs/atisa-menorah/board.json +++ b/libs/atisa-menorah/board.json @@ -1,3 +1,5 @@ +// TODO: finish simplifying this file + { "driveDisplayName": "", "visual": { @@ -114,22 +116,6 @@ } ], "leds": [ - { - "x": 143.64726358645467, - "y": 117.87656419347279, - "w": 7.491260535887221, - "h": 10.307417510334698, - "color": "#ff0000", - "label": "IRRXLED" - }, - { - "x": 98.69974222572388, - "y": 117.87656419347279, - "w": 7.491274487418067, - "h": 10.307417510334698, - "color": "#ff0000", - "label": "IRTXLED" - }, { "x": 152.43907187621588, "y": 12.582555305516507, @@ -246,29 +232,7 @@ "label": "A3" } ], - "buttons": [ - { - "x": 68.85266027547256, - "y": 111.9112648976839, - "w": 14.746670442833569, - "h": 14.746694435684478, - "index": 0 - }, - { - "x": 166.23893562975968, - "y": 111.9112648976839, - "w": 14.748414384189239, - "h": 14.746694435684478, - "index": 1 - }, - { - "x": 147.13927595092585, - "y": 140.0295873507819, - "w": 14.746670442833569, - "h": 14.746694435684478, - "index": 2 - } - ], + "buttons": [], "reset": { "x": 120.62033168383603, "y": 108.7413573209539, diff --git a/libs/atisa-menorah/pxt.json b/libs/atisa-menorah/pxt.json index a89c2611..9f422629 100644 --- a/libs/atisa-menorah/pxt.json +++ b/libs/atisa-menorah/pxt.json @@ -44,7 +44,7 @@ ], "simulator": { "runtime": { - "include": "sim/register" + "include": "sim/visual" }, "visualization": { "include": "sim/visual" diff --git a/libs/atisa-menorah/sim/highlight-corner.ts b/libs/atisa-menorah/sim/highlight-corner.ts new file mode 100644 index 00000000..13501f9d --- /dev/null +++ b/libs/atisa-menorah/sim/highlight-corner.ts @@ -0,0 +1,63 @@ +// puts a highlight overlay in the bottom right of the simulator SVG + + +/// + +// highlight-corner.ts +// Adds/removes a highlight overlay to the bottom right of the simulator SVG +console.warn("highlight-corner.ts loaded"); + +// Make the namespace globally available (not sure if need this) -- added during very first round of debugging +(window as any).atisaMenorahSim = {}; + +namespace atisaMenorahSim { + let highlightRect: SVGRectElement | undefined; + let isShown = false; + + // Call to show or hide the highlight + export function setCornerHighlight(show: boolean) { + console.warn("beginning test."); + if (show === isShown) return; + isShown = show; + const svg = getSimulatorSVG(); + if (!svg) { + console.warn("atisaMenorahSim: Simulator SVG element not found (id 'svg838'). Highlight not shown."); + return; + } + + if (show) { + console.warn("shown."); + if (!highlightRect) { + console.warn("making react elem."); + highlightRect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + highlightRect.setAttribute("x", "390"); // Arbitrary values, adjust as needed + highlightRect.setAttribute("y", "450"); + highlightRect.setAttribute("width", "60"); + highlightRect.setAttribute("height", "60"); + highlightRect.setAttribute("rx", "12"); + highlightRect.setAttribute("ry", "12"); + highlightRect.setAttribute("fill", "#f39c12"); + highlightRect.setAttribute("stroke", "#f39c12"); + highlightRect.setAttribute("stroke-width", "5"); + highlightRect.setAttribute("pointer-events", "none"); + highlightRect.setAttribute("class", "sim-corner-highlight"); + } + svg.appendChild(highlightRect); + } else { + if (highlightRect && svg.contains(highlightRect)) { + console.warn("hidden."); + svg.removeChild(highlightRect); + } + } + } + + // Helper to get the simulator's main SVG element + function getSimulatorSVG(): SVGSVGElement | null { + // Try to find the main simulator SVG by class + console.warn("trying to find main svg."); + const svg = document.querySelector("#svg838"); + return svg && svg instanceof SVGSVGElement ? svg : null; + } +} + +// To use: atisaMenorahSim.setCornerHighlight(true/false) diff --git a/libs/atisa-menorah/sim/menorah-sim-patch.ts b/libs/atisa-menorah/sim/menorah-sim-patch.ts new file mode 100644 index 00000000..3a139e7a --- /dev/null +++ b/libs/atisa-menorah/sim/menorah-sim-patch.ts @@ -0,0 +1,32 @@ +// menorah-sim-patch.ts +// Hooks into pxsim.music.playTone (sound blocks) to highlight the corner when sound is played +console.warn("menorah-sim-patch.ts loaded"); +import "./highlight-corner"; + +declare const pxsim: any; + +declare namespace atisaMenorahSim { + function setCornerHighlight(show: boolean): void; +} + +(function patchMusicSim() { + // Only patch if pxsim and pxsim.music exist + console.warn("enter fxn."); + if (typeof pxsim === "undefined" || !pxsim.music) return; + const origPlayTone = pxsim.music.playTone; + const origStopPlaying = pxsim.AudioState && pxsim.AudioState.prototype.stopPlaying; + + // Patch playTone to show highlight + pxsim.music.playTone = function(...args: any[]) { + atisaMenorahSim.setCornerHighlight(true); + return origPlayTone.apply(this, args); + }; + + // Patch AudioState.stopPlaying to remove highlight + if (origStopPlaying) { + pxsim.AudioState.prototype.stopPlaying = function(...args: any[]) { + atisaMenorahSim.setCornerHighlight(true); + return origStopPlaying.apply(this, args); + }; + } +})(); diff --git a/libs/atisa-menorah/sim/visual.ts b/libs/atisa-menorah/sim/visual.ts new file mode 100644 index 00000000..2d53f01f --- /dev/null +++ b/libs/atisa-menorah/sim/visual.ts @@ -0,0 +1,31 @@ +// this is the basic highlight code needed. All it does is have the highlight show up. no dependency on another component +let highlightRect: SVGRectElement | undefined; + + +function getSimulatorSVG(): SVGSVGElement | null { + // Try to find the main simulator SVG by class + console.warn("trying to find main svg."); + const svg = document.querySelector("#svg838"); + return svg && svg instanceof SVGSVGElement ? svg : null; +} + +const svg = getSimulatorSVG(); + +console.warn("making react elem."); +highlightRect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); +highlightRect.setAttribute("x", "390"); // Arbitrary values, adjust as needed +highlightRect.setAttribute("y", "450"); +highlightRect.setAttribute("width", "60"); +highlightRect.setAttribute("height", "60"); +highlightRect.setAttribute("rx", "12"); +highlightRect.setAttribute("ry", "12"); +highlightRect.setAttribute("fill", "#f39c12"); +highlightRect.setAttribute("stroke", "#f39c12"); +highlightRect.setAttribute("stroke-width", "5"); +highlightRect.setAttribute("pointer-events", "none"); +highlightRect.setAttribute("class", "sim-corner-highlight"); +if (svg) { + svg.appendChild(highlightRect); +} else { + console.error("SVG element not found"); +} \ No newline at end of file