Video summary
In this episode of the Deep Dive series, Tim introduces his latest project: a high-performance sand particle simulation running on CircuitPython using Turbo. The demonstration showcases a physics engine that calculates gravity and collisions for numerous particles while maintaining smooth rendering at approximately 30 frames per second. This performance is achieved by combining Viper-compiled native modules for the mathematical logic with PicoGame for efficient display rendering, offering a significant speed improvement over standard CircuitPython implementations. Tim explains that Turbo allows Python code to be compiled into machine code, bypassing the interpreter loop and enabling direct CPU instructions for integer math, which is crucial for computationally intensive simulations like this one.
A major portion of the discussion focuses on the technical nuances between different compilation methods, specifically the differences between Viper, Native, and standard MicroPython. Tim clarifies that while both Viper and Native compile functions to machine code, they differ in their approach to data types; Viper is a typed system closer to C where variables have fixed types like 32-bit integers, whereas Native preserves full Python object semantics with less speed gain but greater flexibility. The conversation also delves into the complexities of the Turbo shim layer, which manages fallback mechanisms for older firmware versions that cannot yet run compiled modules. Tim questions the utility of silently falling back to slow pure Python code when a project is specifically designed for Turbo, arguing that raising an error might be more helpful for users to identify compatibility issues rather than confusing them with unexpectedly slow performance.
Beyond the core simulation, Tim addresses several areas for future improvement and community support. He plans to refactor the codebase to use clearer variable names and remove unnecessary dependencies like USB video handling, aiming to make the project more accessible and efficient. Additionally, he highlights ongoing work on other Turbo demos, including simulations for fluids, coral growth, and cloth physics, which will be available soon. The episode concludes with Tim sharing updates on his hardware development, such as getting USB host cameras and Bluetooth dongles working with Feather boards, while reminding viewers to check out JP's Product Pick of the Week later in the day to support Adafruit's open-source initiatives.
Read the full video transcript
All right. Hello. Good morning. Uh, what
is up to Liz over in the Discord chat
and forgot to put my keys away.
Put them there for now. Uh, let me
more of these
windows wrangled.
All right, there we are.
So, yes. Good morning, good day.
Welcome. Uh if you are new and don't
know, my name is Tim. I go by Fomy Guy
on GitHub and Discord. I stream at this
time each week, uh Tuesday mornings at
10:00 a.m. Central time. Uh that is 11
a.m. Eastern time here on the Adafruit
channel, working uh most typically on
stuff related to Circuit Python.
Uh you can learn more about Circuit
Python at the main website for the
project here, circuityon.org. This is
basically a version of Python that runs
on these tiny computers called
microcontrollers. Uh there are a bunch
of pictures of them over here. Um the
sort of highlevel quick version idea of
what Circuit Python is. Uh when you use
it on these devices, typically the way
it works, you plug it into your computer
with a USB cable. Uh so they'll have
either USB micro or USBC. You plug it
into your uh computer. It shows up like
a little thumb drive. You can edit a
Python code file on that drive. And when
you save it, the microcontroller
actually will interpret and execute that
Python code for you.
And the code itself can interface with
whatever other uh peripherals you have
hooked up to your microcontroller. So
that might be things like displays or
buttons or lights or sensors, uh inputs,
outputs, uh robotics stuff, you know,
servos, all that sort of stuff can all
be hooked up to these microcontrollers
as well as loads of other uh types of
hardware peripherals and your Python
code. uh in this case can interface with
those peripherals. So you can write
Python code that draws whatever you want
to on the display for instance. Um if
you would like to help support Circuit
Python, one of the easiest ways to do it
is by purchasing hardware from Adafruit.
Uh this is their website adafruit.com.
They pay a team of folks including
myself to work on the Circuit Python
project. It's an open source project.
Everything is uh published on GitHub
under permissive open source licenses.
So anyone is allowed to take that code
uh repurpose it, use it for what you
want uh port it to your own devices. Um
all of that stuff is allowed uh and
Adafruit uh again pays a team of
developers including myself to to
continue working on that. So if you
would like to help support them uh in
Circuit Python as well as uh other um
open- source initiatives that they pay
people to work on that are outside the
Circuit Python world. Okay, they pay
people to work on Arduino drivers and
other things as well. Uh so if you uh
would like to support open source
software and the work that they are uh
you know paying people to do one of the
easiest ways again is purchase hardware
from them. Adafruit.com you can do that
there. Uh looks like uh the shop is
getting loaded up with new uh little
breakouts and sensors.
Uh shout out to Liz. Uh the
libraries for these uh TOF sensors are
in and there is ambient light up now as
well and then a hall effect sensor which
shouldn't need a library I think right
cuz it'll just be on off. So uh all of
those things as well as many other
microcontrollers and many other bits and
bobs uh to make fun and interesting
projects with you can get them over at
adafruit.com. Uh, and if you check back
later today, 300 p p.m. Eastern time,
12:00 p.m. Pacific time, you will find
JP's product pick of the week, where you
can not only help support uh, Adafruit
and the open source software they
support, you can get yourself a, uh,
wonderful discount on whatever the item
selected for this week is.
So, uh, make sure to do that. And diving
in for me this week, I'm headed over to
the learn pages and in particular I have
the turbo learn guide open. Uh and that
is where that is what I am working on
right now. So I have uh this demo
for sand
simulation which I showed a little bit
on my stream this past weekend.
And I am now working on a guide for
although it is going to be a bit
different too. I added the logo to it
this morning. Okay. So there we now have
Adafruit logo. Bit blurry.
Take the camera a second to uh
to focus in.
So we have this uh sand demo now running
under circuit Python using Viper
compiled uh native modules or Viper
compile. So one thing I need to figure
out I'm still a little unclear on is the
difference between Viper and native.
That's actually something we're going to
ask
the robot friend to explain here in just
a minute.
All right. So, we have the sand demo uh
with all these different particles of
sand. And we have the math for this is
now running in one of those compiled uh
Viper modules. And then in this case,
the display rendering
uh is using Picoame, which allows it to
render a little bit more efficiently
than display IO does.
And those two things combined allow us
to have this demo uh with all of these
really nice smooth snappy um
sort of gravity and collision simulation
uh mathematics going on but still
rendering smoothly. I think this one
renders around uh maybe 30 frames a
second or something. I think it's even
printing on this side. We were to open
up the terminal. Yeah, 30 34 32 38. Uh
so it depends on how many particles are
uh moving, right? If if you kind of just
leave it sitting um depending on the
orientation of your sensor, they will
all just settle uh to one spot. And so
when they're all settled, the FPS goes
much higher. And then of course when
they're all moving the FPS drops down a
bit but is still
um you know perfectly good for being
able to get a nice smooth reaction out
of the gravity on it. And certainly
miles and miles and miles better than uh
we would have been able to get in
Circuit Python pre
Turbo and uh Pico game.
Let's see this actually.
And so I will need one more link.
Oops.
Okay. I do actually want to
uh ask about the difference between
native and
Viper. I'm I'm there's kind of two
different things and I'm unclear like I
think sort of that Viper is faster but
maybe chips dependent and native is not.
I'm I'm not sure though. I don't
understand the difference actually. So
let's figure that out. Uh-huh.
Can you tell me the difference between
Viper and Native?
So native, I mean
before turbo stuff had come up, I would
have
said native to me. I interpret that to
mean
essentially like a C module
but I think with
what was added there are decorators. So
so what was added essentially is from
upstream microython
there are decorators like at
microython.viper
and at microython.native native.
So, this is also something I'm a little
unclear on is this turbo directory
and the shim.
Where's the native path?
So native is maybe native is faster.
It prefers the native path. This is a
hypothesis at this point.
Viper and native both compile a Python
function to machine code instead of by
code. The difference is whether it still
behaves like Python. With native
Python semantics, no interpreter loop.
Every value is still a full Python
object.
MP object G A plus B becomes a call into
the same runtime routine as the
interpreter uses. What it saves is the
bite code fetch decode dispatch on each
OP. Almost any Python code works
unchanged and ins can still grow to big
end. Speed up is modest commonly around
1.5 to2. Okay, interesting. So, this
sounds more like what we had before,
just sort of what I would think of as
regular MPY, but that may not be the
case either. This may still be on top of
and in addition to quote unquote regular
MPY. So then Viper though is faster. So
Viper is typed. It's closer to C. Locals
and arguments get machine types. So int
and u in 32 or no u int and u 3 32-bit
registers that wrap on overflow. There
are no big ins. So we can't no integers
bigger than 32 bits.
Boolean pointer pointer 8 pointer 16
pointer 32. Anything else is an object.
So we have int uint boolean pointer the
four pointer types
and then object integer math on typed
value become single CPU instructions
with no runtime calls. Pointer buffer uh
pointer 8 buffer I and pointer 32 array
I become direct memory loads and stores.
There's no bounds checking, no objects
boxing. So that's one thing to be
careful with. Um no bounds checking. So
you need to make sure your code is,
you know, staying within the lines, so
to speak. Uh, overflow wraps silently,
out of range, corrupts memory or
crashes.
Variable can't change types. So yeah,
Viper is faster and more seike. Mixing
typed values with object values, drops
back to slow runtime calls. Speed up on
tight integer buffer loops is often 10
to 50. Both emitters share one
implementation.
Compile picks either native or Viper
around there. It generates code. Viper
annotation. How this shows up in the
repo. Sand is textbook Viper kernel.
Okay. So my next question then is about
the shim
board doesn't Right. Right. Right. Yeah.
Oh
yeah. I mean the board interprets plain
Python
still from code pie.
It doesn't necessarily compile anything.
I would say that's true.
Uh only a thumb emitter is wired up.
Only a thumb emitter. I don't know what
that means.
It's machine code from py turbo build
runs. Mpy cross.
Uh so I have not actually used the turbo
build either. I've been with the turbo
stuff that I have done. I have been just
using MPY cross directly
and I do have at
well I've been using
okay yeah that's what I haven't used
turbo viper decorator I've been using at
mic python viper decorators
but actually one second what is The
what is the sand demo? Shout out to
Mikey as well. Hug report to Mikey
Scalar gave me this uh implementation
for the matrix portal. So I worked on uh
this version and I should say also when
I say worked on I mean huge huge hug
reports uh go to Phil B uh originally
for this code. Phil B created this a
long long time ago uh for LEDs. There
have been Raspberry Pi versions over the
years. There's Arduino version. There's
13 by 9 or whatever LED Featherwing
versions.
Um
Phil B wrote the core code that that
does that does this simulation been
adapted to a few places over the years
and now it is
uh able to run in Circuit Python. So in
sand this is actually at turbo. Okay. So
yeah, one thing that is something I have
not looked into yet is the sort of
circuit python at turbo layer I have
been doing all. So for instance like
this code here
uses this at turbo viper
compared to for instance
this code which is the TFT one which I
did I adapted again from PhilB's code.
This is what's running on here right
now. This is washed out as well. They're
rainbow colors. Think maybe you've been
able to see that as I tilt it. But uh
this is what's running on here. And this
code
just uses MicroPython Viper,
not Turbo Viper.
So, I'm still not quite caught up on the
the actual Turbo CLI
and the shim.
Okay,
it sounds like maybe we do still get a
an improvement by using native um over
what I will refer to as the quote
unquote normal MPY, the old normal MPY.
what NPY has done normally up to this
point. It's like maybe native is still a
little bit faster, but I'm not positive
on that. Uh, but Viper definitely you
just the thing with Viper is you do need
to rewrite it and it really is only
useful for sections of code that are
um doing math inside of a loop on
integers. Basically,
they can be pointer integers. So you
know you can have lists and things as
well but ultimately it boils down to
math on integers.
Um
okay and so then in this sand demo
again thanks to Mikey for this one. So
here it is using
lib turbo which has this gem.
So this is where I'm not I'm not quite
clear on why this exists exactly. So
Turbo runs compiled MPY where the
firmware can source everywhere else.
Your Python
I don't really like it's not really a
complete sentence. I don't know what
that's supposed to mean. puts the native
arts from
the front of cis path
source right be
so we need to have source I'm a little
unclear on that part as well
um
source has
the sand.
Okay, one more here too.
You tell me what the turbo.py
doing.
Although while that's working, we can
read through the code as well. But it
does have this dictionary of
archetypes
which are just numbers to names.
Sounds like cis.implementation.mppy.
report.
Sis
114.
So this is
going to get that value and then shift
it.
sure what that did that take out did it
leave us with just this
I don't really have a clear picture of
uh like a mental picture of bit shift
math all the Yeah.
Bits one and zero
or bits 10 and up.
the table. Okay, so we got 10. It's not
I don't think grabbing the 10 from
there. It's going to binary first.
But 10 here maps to this.
Okay. So this is not
I think I'm starting to understand this
turbo pie shim layer. This is not
necessary. This is not necessary for the
speed up. But what it is is in this
transmission period where we have
like this isn't even officially turned
on yet for instance for the matrix
portal. I have uh did I say anything
about the matrix portal yet? I don't
think so. Um I have the matrix portal
over here which is hooked up as well.
Um, but for instance, it's not actually.
So, right now, I think officially in
released builds, it's in RP
2040 and 2350 only. And then there's a
few more peers in now. I'm not sure if
they've been merged yet or not. Uh, but
I I don't think they were in the release
we just had if they are merged.
Although, again, I'm not sure, like I
said. So I think M M uh 4. So uh SAMD51
is coming up.
Um and then espressive is coming up as
well and some other ports uh also are
going to get enabled but but technically
it's not enabled yet. So, what the shim
is doing is like
handling the fact that the system we're
running on might not be able to use this
yet
because if it's on an old version of
Circuit Python,
it would not be able to import the new
Viper compiled thing. I don't know
exactly what would happen if it I assume
it raised an exception. I'm not sure,
but it would not work one way or
another.
So this is making it so that it will
have a series of fallbacks. Basically it
will try the Viper one.
Although it didn't it say prefers
native.
It prefers native. Run compiled MPY
where the firmware can source everywhere
else.
Pure Python. I guess this is this this
sentence is referring to its own file.
It's saying this file is pure Python
maybe though I don't think it's
necessary. Puts the native arch under
that in front of that with source right
behind it. So a module missing
from the arch still import source
identity decorator. Okay. I don't know
where I saw that.
Functions cannot be Yeah, I don't know
where I saw that. somewhere. I thought I
saw
uh something about preferring native,
but that doesn't actually seem to be the
case in that file at the very least.
This read me.
Did I see that
native loader?
Okay.
I don't know about this.
I don't know about this being hardcoded
to source
because I can imagine a scenario where
you want uh also what's up uh Fed2 sorry
I saw your message just a minute ago I
meant to say hi what's up my man uh nice
to see you my friend I think it was in
the explainer for the difference between
native and viper from the cloud session
that could be
that could Okay.
Yeah. And I was talking about faster
by code.
They hand them the So, so this is
interesting as well. I have to I'm uh I
have to look into decorators. Decorators
are a thing that I've used several times
but never really
looked into the mechanics of in Python.
They're very interesting though.
Um,
I feel like we're missing a potential
fallback.
I feel like we're missing a fallback.
I wish this would stop opening. I
So yeah, I think a few things. One, this
hardcoded as source. I think this could
get unwieldy if you cuz if you have the
same board and let's say you have like
four different Viper projects on it,
right? projects that use Turbo, then
you're going to end up with source
containing
presumably four or more if they have
multiple modules each um Python code
files that are now for different
projects.
I would almost like to see this either
just use the root or
ideally if it's possible to be like
I mean I like to do them per project.
So, so if I'm making the sand demo
project, then I would have like
sand demo as the folder name or you know
something descriptive as the folder name
instead of source and it would have all
the helpers
all the Python modules that that project
uses could go inside there
and then they're still separated. But I
do. So then the other thing is I think
we're missing a layer here
because
Yeah.
I don't know the way this would have
arch
in it is a little weird to me too
because on the same like the devices
archetype architecture architecture will
never change. So you would only ever
have one of these. So, it's like lib,
turbo, and then whichever one you're on,
and there will only be one. It in my
mind, it could just as easily be in
turbo, or it could even just as easily
be in lib.
But,
but remember, we did find that
difference between Viper and native.
They're both different MPY formats.
one of them. Well, no, they both need
the flag, though. They do both need the
flag.
They do both need the flag. And then I
guess because of the way this works
currently, it would fall back to source.
You could put sand.mppy in source. You
could have
uh you could have a non turbo MPY file.
You could have an old style MPY in here.
It would actually load that. Okay. So,
we're not really Yeah, we're not really
missing a layer like a fallback. I was
thinking we were going straight from if
the Viper one doesn't exist, then we are
forced into Python directly, which I
will say the way this is documented
makes it seem like that a little bit.
Um,
but in reality, the way it will behave
is you could actually have sand.mppy.
You could have a old nonviper,
non-native, non-turbo at all, just
regular old MPY, whatever the standard
MPY was before all this. You could have
that here. It would still be it would
still be what gets imported. As long as
you don't have both. If you have both,
then the plain tech and the plain text
one will get imported.
At least that's the way it is for lib
and root. I assume it's that way for
every folder.
I think for I think uh it's for
packaging so that a release could
contain MPY and ESP
from the release perspective
in a release. That that does make sense
to me.
Like a release of a project that runs on
multiple devices.
That would Yeah. Yeah. And that would
explain Arch, but you would only you
don't really need all of those on your
one device, right? in this in in a
hypothetical project that supports
different architectures,
you don't need or necessarily want the
other architectures compiled code on the
devices that don't support it. So, you
do still end up only with one. And I
think like in an ideal world,
we will have hooked up the uh I don't
actually have an example of the button,
but like on the code pages where there's
a get get uh what is it? Project
download project bundle.
That's project bundle, right?
Yeah, download project. So on the I
think the idea is with this button
there's a tool behind this called
bundlefly which could package up
everything
for the device you're on as long as it
knows which device you're on.
Also saw in the code it asked about
what's the arch to load that specific.
Yeah, that's that's another thing that's
a little weird to me is like
well I mean ultimately that boils down
to the same choice of having the folder
with the architecture name right the
reason why we need to have this mapped
is because it's these are the folders
that it is wanting inside of Turbo here.
So, X to win.
Yeah.
I don't know if that needs to live on
the I don't know if that needs to live
on the device, though. This feels like
extra complexity for the final device to
me
cuz the final device is only one
architecture.
If
the bundler,
the thing behind this button can package
it without the architecture folder,
then there's no need to have this
mapping because we never need to know
the name of this folder.
We still can check just yes or no like
is native supported or not. And we can
still
um do this this path trick to to put in
the different
the different things in the path there.
But then we don't end up with this cuz
to me this code reads like it's picking
with like picking from available
architectures. I don't know. I just it
this feels like a packaging detail, not
a running on the device detail to me. It
feels like a a a
thing we don't it doesn't need to be on
the device. This shim that's like what
do I do for all these different
architectures when that shim is only
ever going to run on that that one?
Well, I mean, the same shim runs on
different ones, I suppose, but
if it were refactored a little bit, it
would not need this whole idea of which
one is which.
And it doesn't seem to do any
enforcement either, I don't think.
Right. So, like this
this module is not helping you if you
have the wrong one of these. It's not
like telling you, hey, we're on X to
win, but you have ARM 7,
therefore we fall back to Python code or
something. It doesn't seem to be doing
that either.
For saving space, you only need Yeah.
Extensa and that's it on the board. ease
of instructions. You just say copy these
to lib.
Circup uh totally I think is part of the
answer to this as well. Yeah, good call
uh Fede for sure. I think circup is part
of the answer to this to this to this
problem to the scenario as well. Circup
I view circup as very similar to this
the bundle thing that's behind this
button basically. Uh and so circup I
would love
uh and I think it will as well. we'll
we'll get to the point where it is built
in to support this stuff as well. The
other thing that it's telling uh is is
that telling a user if you have ESP you
need to remember extensib.
Yeah, I think but I think where I land
is it's easier to just tell the user to
copy it to lib
and not worry about the architecture at
all and have the bundling tools
have the bundling tools
pull the correct architecture. So
instead of having an extin folder on my
matrix portal for instance,
it would have just either just lib like
it does today or if we want to keep
turbo then it could be lib turbo
but it would have no extensive whim and
instead
it the bundler. So the thing that's
behind this button and circup both would
know to check whenever you install a
module.
I will say circup is a bit weird because
it's for library code more than project
code. Um, but idea being the project
bundler and circup or or some tool would
know would would check your device and
they would say, "Hey, you're on an
extensive wind device. So, I'm going to
give you compiled code for that, but I'm
just going to put it in lib turbo or
just lib by itself. Either one.
Okay. But I understand it a lot better
which is good. Um
and then these are the decorators which
do what again? Identity decorators.
Turbo Turbo Native and Viper are markers
for the Oh, okay. They don't do anything
in Python code.
Okay. And then these are only these must
be only for if you use the turbo
actual turbo CLI as well.
Yeah. I don't know. I at the end of the
day I think uh it's worth a discussion.
It's not really just
it's not really just up to me. I could
see some like upside to having it
document the architecture there.
Uh, but I can also see some confusion
where people are like, do I need to have
all these or or if the bundler gives
them all of them, they copy all of them.
That I don't think we want. Ideally, we
want the bundles to know which device
you're you're running on. Circuit, it's
easy because it can just check the
device. The bundler here is a little
trickier because obviously it can't just
check the device. But what we have
working for us here is these tend to be
on a guide page which tend to be for a
project that is for a specific
like board. Uh in this case it's not
right because it's an example of this
breakout. But this is not something that
would really benefit from turbo anyway.
We would almost, you know what we would
need is like we would almost need a
comment or something at the top of the
file that like declares
for the bundler what the architecture is
supposed to be. And I think we need that
either way, right? Whether we keep that
folder or we don't.
Somehow the bundler needs to know what
architecture it's need it wants to
bundle for.
Yeah. And I think some kind of like
comment or something near the top is
probably the easiest way.
Or maybe like a hidden file or something
in the same folder.
Okay.
Yeah. I don't I
don't know about this about this shim
necessarily.
I think the main part of this shim in my
mind
I think I part of the I guess where I'm
stuck a little bit is this shim kind of
it
implements behavior that we sort have
already with because because like
Circuit Python by default will
choose the right import when you have
multiple ones available.
Well, what it calls the right I I guess
what this does is it
Yeah. Okay. What this does is it it's
really back to what I was talking about
at the very beginning, which is the fact
that we don't have support on old
versions, right? So if you have a matrix
portal running old circuit Python, it's
not updated yet,
and you run a project with this shim on
it,
the project will have the capability to
fall back to raw Python. So it will do
something instead of error,
but it will run way slower than it would
if you had newer
circuit Python,
which is a tradeoff. I almost wonder if
it would be
I almost wonder if it would be worth
like do we want it to go do we want it
to fall back to slow? I could almost see
a case for like if you have a thing that
is from a project for Turbo, the whole
point of it is to run that section in
Turbo and run faster.
I can see the upside in it not crashing
if you're on an old o uh version of
Circuit Python, but you are still
missing out on what I would argue is
kind of the main point of the project,
right? because it's at this point it's a
turbo project meant to take advantage of
the new stuff. So you
are then running it in the old way where
it's slow.
I could almost see it being better or
less confusing, I guess, if it were to
just crash instead of run slowly.
Because if it crashes, you know,
immediately visually from the serial
terminal,
there's going to be an error that's
like, we tried to import this thing and
it failed. I I presume some kind of
error like that will happen
as compared to with this shim.
It silently picks a slower one so
there's no
like I envision a person coming to the
help with channel and being like I'm
running this turbo thing and it's going
super slow. What's the problem?
Whereas if it errored out in this
scenario
they would be running this turbo thing.
They would see the error. They may still
come to the help and be like, I'm
running this thing and it's crashing.
What's the problem? But they may also
see the error and be like, oh, the
import's not working and maybe we have
an FAQ or something. And it points them
in the right direction. It it it feels
like easier breadcrumbs to follow if it
just raises
than falling back to the slow one
because if it falls back to the slow
one, it's on the user to like notice by
looking at it that it's slower than it
should be. And the user may have never
seen the fast version in person, right?
Like presumably they maybe have seen the
guide which has GIFs or videos, but they
maybe found it on GitHub and haven't
even seen the guide or they maybe have
seen only the guide and never seen it in
person. They're like trying to make a
judgment call of is it as fast as it's
supposed to be
um to know if it's working or not, which
feels tough to me.
Thinking of uh let me see here
quick related topic tested yesterday
circuit Python rest with mandelroad
example 7.5 times faster than turbo on
an M7. Wow, that's pretty crazy.
Currently porting and testing the sans
code. Oh, nice. Thinking about porting
ULAB to Rust as well. Interesting.
And FedEx says, "Yes, I would not like a
fallback if the idea is to have the
screen move in the sand faster than have
instructions." Yeah, I think I'm
I think I'm coming around to that stance
as well. I think I lean like right now,
I would say I lean the direction of I
think the exception is probably more
helpful, but I'm not fully decided all
the way, but I am like I'm headed in
that direction. the slow the the the
slow fallback. Again, I can see the
upside of it because you get something
instead of a crash, but I feel like the
something you get might be tough for a
person to actually know that what
they're looking at is a consequence of
it not working how it's supposed to.
Uh, I think the fallback is more for
Turbo as a dev project than the guides
that use Turbo. Yeah.
And it does.
Yeah.
Yeah, it definitely does help. It does
make it a lot easier to go back and
forth.
Okay.
Okay, so these are I mean these are a
couple of things I'll uh discuss a
little bit with Mikey I think and the
rest of the team as well. Maybe this
would be a good in the weeds
in the weeds thing to dig into a little
bit in the future.
Um
yeah.
Yeah. Yeah, I think the exception makes
makes a little bit more sense in my
mind.
Um, but I can see it both ways too. Uh,
Okay, one thing I did on this one
earlier is make these
a lot easier to Understand
all of this physics before was like uh
single and double letter variable names.
There's some room for improvement still
with the constants which are basically
indexes.
They mostly have comments. I might still
go through and rename these honestly.
But again, this is all basically Phil
Bee's code from which I actually didn't
when I first started working on this, I
did not I hadn't found
it in this browser.
I had not found this actual pixel dust
repo. When I first started this the
other day, I had
not this code. It was
animated sand.
I think this is the code I started from
or
yeah
was either that or a panel.
actually. I think it might have been
this one
or no cuz this doesn't have code. That's
right. This is the handles and this is
hourglass which is a little bit
different.
Yeah, I think it was the 13 by9 actually
this one. But I believe the code in this
one was based on
pixel dust cuz it also
was fil
but I did later find that there is
actual pixel dust library as well which
it does look like is the code that was
running
in that guide. That was just the handles
actually.
I do think the constants would be good
even though they have comments here.
IP. key.
I'm not sure why P is what is
what's prepended to all of these.
E parameter
might be parameter because it does pass
by
index basically.
Some of these could still be improved
for sure. like these.
So, nothing in here says what
He is this speed
and it should
I guess it's the
I don't know nothing in there says what
it This
fantasy.
Nothing actually calls it from here.
We would have to look in code pie.
Back up.
Take this part out for the published
one.
I used USB video before I had a display
connected.
Where does P get assigned? So, we have
this P here, but it's
okay. Still, there's definitely still
room for improvement. Uh, this got a lot
better,
but should be still better. Like these
used to be two letters, one letter.
There's a seed or random was used a lot
or LCG or something I think is an
acronym that was used for random.
But especially where code pie is calling
into this, it could be a lot better. And
Code Pi itself could be a lot better as
well. So I think that's what I will do
next. And also rip out the USB video
stuff. We don't need that.
Uh it doesn't need to check targets. It
can just assume the ILI because this is
kind of targeting Metro
with the TFT shield. So
okay,
I'm going to clean that up a bit more.
But that is basically uh where my head's
right now is Turbo uh all the things. I
have the sand demo that I've been
working on. This is the first uh guide
that I will publish for Turbo stuff, but
I do have a couple of other uh demos
that will come out perhaps after that or
I'll throw them up on Playground or
somewhere if they don't uh become
official guides. There's like a fluids
one, there's a coral one, there's a
cloth one which is pretty cool. Um, if
folks are interested in those, you can
check back on my channel uh from the
stream this past weekend on Saturday. I
played with those a bit. Um, and
before I go, I will leave you with the
reminder for JP's product pick of the
week. Uh, later on today, you can get
yourself a great discount on a wonderful
product, whatever it is. And uh, as
always, when you purchase from uh,
Adafruit, you are helping them support
open source and all of us that they pay
to work on it. Uh, congrats again on USB
camera. It seems very interesting. Yeah,
camera I think is going to be cool as
well. I did get uh I did get USB host
camera working. Um, that was something I
mentioned in the meeting yesterday. Uh,
for fruit jam, there are some changes in
upstream picop USB um that we'll need to
either get merged in or we'll have to
use our own fork for that. And actually
last night uh which I don't think I
didn't mention in the meeting I don't
think but last night one of the things I
worked on was um USB host Bluetooth. So
the ability to use a Bluetooth dongle.
Um I'm working with a specific one. I
forget the ex it's a realtech one. Um
and I'm focused mainly on that one
specific one. Not a generalized thing,
but uh I was able to get a Feather USB
host with a Bluetooth dongle
talking to a Circuit Playground
Bluefruit. So, uh pretty cool stuff
going on there as well, I think. Um so,
yeah, keep keep uh keep a lookout for
that stuff coming up. Um like I said, JP
later today. That is at 3:00 p.m.
Eastern, 12:00 p.m. Pacific. And I
should be back next week at the usual
time here on Tuesday. uh 10 a.m. Central
time for my stream as well. Until then,
I will bid you so long farewell. Thank
you for watching and hope you have a
wonderful day and a wonderful week.