6. Frequently Asked Questions (FAQ)¶
To be rather blunt, I’m not a fan of the Sense HAT’s official API. This probably sounds a bit strange coming from someone who played a small part in making it (I wrote the joystick handling side of it, and later the desktop Sense HAT emulator)! Originally pisense was my attempt, back when the Sense HAT was relatively new, to design an API the way I wanted. It was a rough experiment and I didn’t want to “pollute” the space by offering a competing API to the official one, so I left it as just that: an experiment available from my GitHub pages, but not properly documented, tested, or packaged.
Over the years, I’ve wanted to actually use the Sense HAT in a few applications and each time I’ve tried, I’ve found myself frustrated by the inconsistencies or short-comings in the official API. Eventually that came to a head and I decided to pull pisense out of storage and polish it up for serious use (I considered including it statically in applications I built, but that seemed ugly).
To be clear: this is not an attempt to supplant the official API. If you’re a teacher in education you’re almost certainly better off with the official API. All the learning resources are built for it, the community support is there for it, and it’s the only API accepted for the fabulous Astro Pi mission. Stop reading this and go learn that one.
6.2. You still haven’t answered why…¶
All the teachers gone? Okay. I don’t want to put you off using the official API, but here’s what I don’t like about it:
- It pulls in numpy as a dependency. So does pisense, but we actually use it for more than rotating the display (seriously, that’s all the official API uses it for). Why pull in numpy (a huge dependency) and then not use its signature class (an n-dimensional array) for your two dimensional display?
- It pulls in PIL as a dependency. Again, so does pisense, but we use it for a little more than a single method which just loads images for display. How about presenting the display as a PIL image for manipulation? Or using the drawing and scaling capabilities for animation? Font support for text display? Oh, and our image conversions don’t rely on nested lists …
- Fixed width fonts for scrolling text? Urgh.
- The stick interface (yes, the one I wrote …) isn’t bad, but it’s not
great. The real stroke of genius in pisense (which sadly I can’t take
credit for: yet again, it was one of Ben Nuttall’s fabulous notions) was
heldinto its own value in the
StickEventtuple so that release events can tell if the button was previously held.
- Everything is conflated into a single class (except the joystick) so if you don’t want certain functionality: tough, you still have to deal with all the initialization and memory usage for it (okay, that’s just a nitpick really).
- Tons of duplicated ways of doing things. I want the temperature; do I call
get_temperature()method, or the
get_temperature_from_humidity()method, or query the
temperatureproperty, or the
tempproperty? Actually it doesn’t matter; they all do the same thing (call
- Several limitations in the API. I want both the raw accelerometer readings
(in g, because degrees really are useless for that) and the magnetometer
readings. The only way to do this is to query
compass_raw(or call their duplicated methods). However, under the covers this causes two separate IMU reads with all the attendant overhead and inconsistency that implies. There’s no way to get this set of data from a single IMU read.
I’m not intending this to be the simplest interface to the Sense HAT. The official API is probably easier to get going with. My feeling is that I’d prefer an API that was a little harder to get started with if it allowed me more scope to “get things done”.
6.3. Why are you using single precision floats in the display?!¶
Under the covers, the Sense HAT’s display framebuffer stores pixel information in RGB565 format. That’s 5-bits for red and blue, and 6-bits for green. The 32-bit single-precision floating point format used in pisense still uses 23-bits for the mantissa; more than enough to represent the 5 or 6-bits of data for each pixel.
Why not use RGB565 directly? We do: the
provides an array backed by the actual framebuffer in RGB565 format, if you
really want the fastest, lowest level access.
However, for ease of use I wanted the array format to be compatible with my colorzero library, which meant using a floating point format. The smaller the format, the more efficient the library as there’s less data to chuck around and crunch (ideally I wanted it to perform reasonably on the smallest Pi platforms like the old A+). During development, this library used the rather obscure half-precision floating point format which is only 16-bits in size (and provides 11-bits for the mantissa). However, hardware support for this floating point format is only present on some Pi models and as best as I can tell isn’t supported at all in Raspbian’s 32-bit userland. In tests, the single precision format turned out to be the fastest so that’s what the library uses.
6.4. Why are orientation and gyroscopic values in radians, not degrees?¶
Firstly, there’s routines built into Python’s standard library for conversion so this is trivial to achieve without the library duplicating it. However, the more important reason is not to clutter the API with unnecessary attributes.
Degrees are probably simpler to look at as pure values, but they’re
considerably less useful to use in practice. This is because almost every
routine you are likely to use these values with (all trigonometric routines for
instance), only accept radians. This is why the
repr() of the orientation
includes degree values (because they’re useful values to “eyeball”) but the
actual class doesn’t include such values.
If it did, I’d likely name them things like
roll_degrees at which point
you’re typing almost as much as