Notes and adventures with my tildagon. Don't expect this stuff to make too much sense.
the battery leaked a bit while my tildagon was waiting otherwise patiently for my attention
many people in their christmas holidays queuing up. more berlin dogshit.
after spray, everything except the down button works. very occasionally the down button does work, but mostly it either makes no input, or starts input clicks repeatedly which stops on reset.
ordered replacement ribbon cable (x5) from china. using link from tildagon website. a few days shipping - perhaps longer getting from Liege to my door than from China to Liege, much postage. it arrived without any customs trouble, which i was unsure about given recent changes in de-minimis exemptions.
while its disappointing that the down button doesn't work right now, this isn't overall a disappointment: it forced me to pay attention to whats going on with the hardware much more than if I was just tinkering, and that was interesting.
Protoboard Hexpansion by jakew
even with nothing on at all these boards still do something: the tildagon OS notices a board plugged in and turns on the back-LED above that board. and also emits a log message to the serial console
soldered a header on. turns out that board is a fraction of a mm too short for a header to fit and for the hexpansion connector to go in completely but only very slightly out so it "works".
at least for this use case, probably EMF Badge Interposer Hexpansion by Gavin's Creations would have been better.
Low speed pins couldn't flash my LED with the firmware I had. But that was documented on the tildagon website for that firmware version. so I rebuilt the firmware from github.
I didn't build an app to flash the LEDs: I used the USB serial port to ctrl-C out of the firmware and run pin commands in the micropython REPL.
Pretty much I followed the instructions in the readme of emfcamp/badge-2024-software and it worked. It was a bit confusing about how to get the badge into firmware loading mode. I don't quite believe the button sequence in that README.
pimoroni rainbow hat for raspberry pi - I had this sitting around in my box, waiting for a use. The piezo there is powered off 5v, not 3v, in as much as I needed to feed 3.3v into the 5v supply not the 3.3v supply on the connector
PWM module on any of the high speed pins. I didn't try the low speed pins. Set duty to 0 or 100 for off, and to 50% (512/1023) for tone. Set pwm frequency to change the frequency of the tone.
hook into eventbus to make it beep when Something Happens (eg hexpansion insert/remove)
the driver app doesn't start at startup: i guess if it was in a hexpansion EEPROM, it would? but I don't have one of those.
this is interesting enough to think about getting components soldered onto protoboard
test app that counts button presses using two different callbacks, one of each synchronicity.
tildagon-eventcounter app
Documentation PR #281Doesn't look very good on such a small size, and especially bad because with 12 leds it rapidly turns into a boring pattern due to being a nice round number. I added some randomisation and colours which makes it look better.
it was a good first app though and I have a few other circular ideas to play with.
tildagon-pattern-ca app
in the badge-2024-software repo theres PR #235 unmerged, working on pluggable patterns via apps, which is otherwise a bit weirdly supported right now.
eventbus usage: the docs and examples I've seen attach events to the eventbus in app __init__ and then recommend removing them at minimise time. These aren't symmetric: when the app is reselected on the launcher, the events aren't reattached. I made a new foregrounding concept in my apps using a boolean. but I wonder if there's a better way to do it? I think it could be done on reactivate event notification, for example.
I couldn't remember what the 6 buttons on the tildagon conventially do, except for up/down which are in up down positions. Get my sharpie out and annotate the front board. Also fill my name in on the cloud space that perhaps is there for that purpose.
the down button is working for its longest ever! 10 minutes so far...
playing round with ideas for an on-badge sequencer/programmer app. learning about ctx library for UI. got a play-only UI going. but it can't be used for on-badge programming which is the whole point...
now trying out the Menu UI... the example is a bit confusing, about how to activate/deactivate menu inside bigger application but I think I see what is going on now and I'm making my app have a "UI delegation" mode where I can hand off to other components like Menu easily for UI modal stuff - essentially foregrounding different bits of code with their own update/draw methods. So maybe the whole thing should be made of UI delegates?
I've got a decent sketch of an interactive program scroller and three modes: play, edit, menu - with the menu not doing anything, but it needs to lead into editing steps
A few days after that last chemical rinse, the down button is still working! (9th January 2026)
learning how to make menus actually do something (the two callbacks and how to disable menu UI once user has chosen something). there's a menu._cleanup method that although the _ hints it is internal, seems to actually be the way to stop a menu - i.e. that's the piece that unregisters the button event hooks, sort of the equivalent of backgrounding it.
Another weirdness in menus seems to be that I get a select event immediately when the menu is rendered. Possibly because I'm constructing it inside the event handler for button down, and so (as deliberately labelled as undefined behaviour in the in-source documentation) the newly registered event handler in the menu for the same event is allowed to be fired. Well that's awkward. Which means maybe I have to construct the menu outside of the event handler. e.g. in update. I think that is straightforward to do.
Functionality implemented today: colour picker. step deleting. pause steps. loop counter steps.
I've previously wondered about how to correctly detect when an app is put back in the foreground, so it can re-attach its button events. Some of the documentation talks about doing this in __init__ which doesn't work when you go back to the app afer minimising it: the app object already exists and is not created again, so __init__ doesn't run again.
So I've been doing this in update, with a flag to detect when update runs when the app thinks it was previously backgrounded. But I'm hitting a race condition - after setting the app to be minimised, update gets called afterwards at least once, and that thinks the app has been brought right back into the foreground and does the foregrounding behaviour. This is causing a problem with pattern generation: I re-enable the patterns as part of backgrounding, and the pattern regenerates for a frame (or maybe a few frames) and then my app disables patterns again and so the pattern freezes.
Another way I thought about was listening to foregrounding events, and so I tried that out and it seems to work ok.
Earlier, I wired a piezo buzzer into a hexpansion, and made it beep on all delivered events - which is mostly apps coming to the foreground/background and hexpansion insert/remove. But how can I make it do more with what is happening on the tildagon? That led to:
How does an arbitrary app do "something" with arbitrary hexpansions?
How does a hexpansion find "stuff" to do?
I'm experimenting with a new set of system events, Emote Events, that an app can fired onto the event bus when an interesting positive or negative (good/bad) thing happens in that app. Hexpansion drivers (or other code) can listen for those events and drive their hexpansion to give a "good feeling" or "bad feeling" - what ever that means for that particular hexpansion. For example, LEDs might flash green/red, but a sound board might play a happy or sad sound. That range of meaning provides pressure for the emote events to be: semantic (don't say "flash green", say "emote happiness") and constrained.
I'm trying this out on my own firmware build. The events need to be in the base firmware, absent techniques for working with "installable events" - such as module loading/detection.
The modifications to the firmware are fairly small: three empty class definitions in modules/events/
I mentioned this in badge IRC and a few people seemed in favour, so I'll make some PRs for this.
I made sequencer app able to trigger sections of code, based on two triggers: Play starts (the existing implicit behaviour) and when a button is pressed.
I made three firmware PRs:
#246 - to add emote events
#247 - to make pattern mirroring settings controllable
#248 - to make pattern mirroring mirror onto the back live (which I think was the intention of the original author), because once I made the setting to turn mirroring on, it turned out the existing mirroring impl didn't look nice.
made a wifi-strength flame pattern, inspired by the datenklo poles. it's not doing the colour curves enough to make me happy. but otherwise I'm mostly happy with the effect.
my flame app makes the launcher UI extremely sluggish - 1 second or so latency on up/down keypresses. I wonder why. an excuse to poke inside asyncio and use my own hacked up micropython. which the docker build image for tildagon makes pretty easy: it builds from a source checkout so that is easily hackable.
I added some prints on the asyncio task scheduler scheduling tasks or being idle. I don't get any idles. which surprises me - I guess there's some task that is hard looping? maybe that's ok as long as it is still giving up the scheduler.
I can see the scheduler running ok in the trouble some situation. I can see prints take 10ms or so per line, which I guess makes sense at 115200 baud on the serial console, and so putting in debugging prints slows down the scheduler. I can see the IRQs from buttons firing immediately, when I press a button. My first hypothesis was my app was somehow interfering with button IRQs by talking to wifi and LEDs so much. But that doesn't seem to be true. So is something weird happening in the event bus that makes events be delivered slowly?
Let's stick some debugs in the eventbus code for event arrival and dispatch.
Looks like my app is making a RequestForegroundPop event repeatedly - this happens in update(), but update should be suspended when the first RequestForegroundPop event happens... ???
Turns out that the pausing of update() only happens if the run loop subsequently makes a render - because that's where the suspend happens. And because I didn't have any UI rendering to do, I made my update() return False to inhibit that. Thinking it might make things a tiny bit faster.
Remove that return False and it all works properly.
Now wiflame and sequencer conflict on their use of LEDs: sequencer turns off the pattern. but wiflame isn't acting as a pattern. That PR i mentioned before, #235 to make apps be able to run through the pattern mechanisms - that's probably the right place for wiflame and the cellular automata pattern I made before. So maybe I can pull that branch into my local firmware and try out that feature.
I found another speaker (that came with a bbc micro:bit kit) that is a speaker rather than a piezo. with an onboard amplifier of some kind. The exact same PWM driver code already installed on my tildagon is enough to drive that and it is much louder, more reminiscent of a BBC Micro inbuilt speaker.
PR #235 which adds user-installable patterns, merges cleanly into my firmware. I ported my two patterns to that API and that worked pretty straightforwardly. Made a comment on the UI.
Got my tildagon in a state where it needed external intervention (which I am totally set up to do) - a user pattern which crashes at __init__ time. Patched a try/except into my firmware so that it carries on rather than breaks the boot.
Splitting out the colour picker UI from the LED step creator UI, because the LED step also needs an LED picker: I want it to let you pick which LEDs to set the colour of, not just pick the colour.
Do a bit of work on the eventbus documentation, driven by wanting a place to put the documentation for emote events.
I'd like to build my own hexpansion PCB. Thinking about what I'd like. Especially as the cost is in the setup/delivery, and the per-board marginal cost is quite low, this points towards me designing something I can give away 20 of, in addition to whatever I use myself.
Current sketch is a connector PCB that has 14 through-the-hole pins eg for headers, and 5 (2x power + 3x GPIO) pads for banana plugs and crocodile clips (like the micro:bit edge connector without the in-between tracks they have for their edge connector). The 5 pads are an attempt at letting you build a flashing LED / button kind of project "right away" and also some base area to use for sticking onto further boards that attach to the 14-pin header. The two immediate projects are: stick on a mini-breadboard, so prototypes can actually be worn around. Attach bornhack 2021 badge boad - eg with non-permanent double-sided tape between that area and the back of the bornhack badge. Attach tidal badge as a serial terminal display / joystick input
so maybe time to have a play in kicad to see what it looks like more seriously.
After a few weeks of working, I left the tildagon powered down for a few days and the down button has stopped working.
Test out an app I helped someone get started with on IRC earlier: a badge app
Ordered a load of bits from Pimoroni, now waiting for the shipment: a GPS module, some LED noodles, a CO2 sensor, an 8x8 infrared time-of-flight distance sensor, three LED letters B E N, with the intention of at least doing something badgy with all of these.
I want emotes to make this flash green or red, which means coordination needs to be done with hexpansion LED code. Split into a separate manager which is entirely event drive, using hexpansion events and emoji events.
Specifically, I want to be able to show Sequencer at Show Us Your Screens next week.
It seems to work. Though I will also take the badge to show stuff like IMU interaction.
herehttps://apps.badge.emfcamp.org/apps/03402032/
Took a few tries to get the metadata right to get it in the pattern category
Tried to try this in the simulator. I needed to patch the simulator to make patterns/ appear in a fake location, like it already does for apps/. And the settings dialog box hangs. I haven't looked why.
I noticed colours seeming to saturate too much in a bit of experimentation. Someone else on IRC appeared with a similar problem, so I investigated the ctx. Looks like ctx.rgb takes a float from 0..1, but the reference material at https://tildagon.badge.emfcamp.org/tildagon-apps/reference/ctx/ has examples going up to 255, which is saturating at 1.
Made a nice hal-eye demonstrator to show the actual possible gradient of colours.
Now I can go fix up the bug in sequencer app.
I've got 5 breakout garden boards lined up in front of me. I want to use two of them this week for FOSDEM: the co2 sensor and the GPS. I've got another breakout garden board that I already soldered pins onto, so it won't fit into this setup. I guess I can take them off. It's a colour sensor and one of the interesting questions I have for sequencer is: what are interesting ways to input colours?
First, I'll do a bit of soldering to turn my existing out-of-spec breakout board into something I can use with my breakout garden breakout board. So I can work on the software/i2c interfacing of things. Then when I see that's working, maybe it will tempt me into building a proper 3x breakout garden board on the other protohex that I got.
I realised that for i2c + low speed interrupts, I don't need the back row (closest to the badge) row of pins, which were the ones causing trouble, as long as I add on somewhere to get power - the board already distributes that down the two side columns, far from the badge/physical conflict zone.
Create an I2C object with the appropriate hexpansion port number and run i2c.scan() and I can see the i2c addresses of the various devices as I click them into the single breakout garden ports. So thats enough wiring for experimenting with i2c protocol software.
Learning a bit how about the tildagon firmware does i2c (because its going via that multiplexer thing). Seems to actually behave as if the multiplexer isn't there, API-wise, because theres a special i2c implementation for tildagon that knows about the multiplexor.
Got it decoding i2c responses, 554 ppm CO2 where I'm sitting in my apartment. Time to open the door and see what happens... it should fall to somewhere low 400s I hope.
16:20:16 554
--opened door--
16:20:45 547
16:21:02 553
16:21:49 618
16:22:16 624
16:23:09 972
16:23:40 1039
... uuuuh i feel like this should be going down not up?
16:24:33 996
16:25:47 770
16:26:26 731
16:27:02 686
16:28:26 546
16:28:55 532
16:30:30 518
16:31:28 683
16:32:19 840
... ok what if i stop sitting right here with it on my desk near my face?
16:32:58 871
16:33:37 822
16:35:26 536
16:37:09 466
16:39:40 412
... ok i've moved back to my desk it looks like it was going down
16:39:59 411
16:41:06 557
16:42:12 783
.. ok lets move the sensor behind my laptop screen about a metre away from me, over to the far side of my table
16:43:24 733
16:43:44 714
16:45:19 534
16:46:22 456
16:48:08 420
.. ok not sitting right over the sensor seems to be doing ok. the room is still being ventilated by my open apartment door
.. i've closed the door now
16:52:03 398
Now I am successfully reading in data from the i2c co2 sensor, switch to one of the other breakout garden boards I want for FOSDEM: gps.
Once I looked at the library and had a play it was fairly straightforward to see how to read this as if it was a serial stream. Although it likes to stick \n as padding bytes in there which makes things a bit weird although shouldn't affect the protocol: \r is used for end of line so I can ignore \n entirely.
So its merrily outputting a bunch of NMEA sentences every second.
But, sitting at my desk, it can't see any satellites.
It's also doing a cold start, and I have no idea what that would look like in the output messages.
So I've moved over near the window with at least a little bit of sky visible, although not a huge amount in this courtyard.
There's even a wikipedia page specifically about time to first fix for GPS, https://en.wikipedia.org/wiki/Time_to_first_fix which talks about the almanac being transmitted every 12.5 minutes.
And after about 5 minutes at the window, I see $GLGSV,1,1,01,75,,,20*64 which I think says it is seeing GLONASS satellite 75.
and then by the time I've written that, it's gone away again but I can see a GPS satellite 08 now.
various satellites coming into view from GPS and GLONASS. but never more than one at once and the SNR always seems low.
so after an hour, how about putting this out on my balcony which might have some more sky? it's cold... but dry at least. and I can leave my laptop inside on the end of the USB cable console.
now it sees 2 GPS and 1 GLONASS satellite.
and 5 mins later, 3 GPS and 2 GLONASS. still now fix though.
and more later (an hour later)... its got 3 satellites on each of GPS and GLONASS and the green PPS LED is flashing. Here's the location message: $GNRMC,183114.000,A,5230.7803,N,01327.3842,E,0.00,171.87,280126,,,A*7B
now it has 9 satellives on GPS and 10 on GLONASS, so its having to send three G?GSV messages for each of those systems to enumerate them
There's some meta data I can probably visualize...
The coordinates even roughly match up with what wikipedia says for where I live.
Here's a whole 1s cycle, the verbose version because not every line is output every second.
$GNGGA,184456.000,5230.7785,N,01327.3702,E,1,7,1.56,46.3,M,44.6,M,,*72 $GPGSA,A,3,10,08,02,,,,,,,,,,1.81,1.56,0.92*08 $GLGSA,A,3,75,69,76,85,,,,,,,,,1.81,1.56,0.92*1E $GPGSV,3,1,10,08,73,235,17,10,62,072,30,27,55,157,16,02,51,277,27*77 $GPGSV,3,2,10,32,25,126,,23,24,050,,01,19,266,16,14,10,330,*70 $GPGSV,3,3,10,16,06,189,,41,,,*4C $GLGSV,3,1,09,85,66,322,42,69,52,088,18,70,29,155,,76,27,315,26*6D $GLGSV,3,2,09,68,25,029,,75,23,253,19,86,09,287,,77,06,357,*6D $GLGSV,3,3,09,83,02,098,*54 $GNRMC,184456.000,A,5230.7785,N,01327.3702,E,0.00,343.68,280126,,,A*77 $GNVTG,343.68,T,,M,0.00,N,0.00,K,A*29
Now what happens if i bring it back inside to my desk?
It still seems to think it can see 19 satellites... lets give it a while to see if they go away? it's lost its fix and the green LED has stopped flashing on the board.
ok, so i'm generally happy I can get the info I want from this GPS.
Especially it gives me a time source. Although when I have internet I should also be able to NTP (I think the badge is not already doing that)...
and the next breakout to try is the RTC module I got for my bike but never got round to using. or even trying out.
A little interlude learning how to use the power module for looking at power supply status, and os.statvfs to see disk usage. Both of those are things I'd like to log in my data logger.
I got this as noted above for my bike, for datalogging there. I never got round to using it. So now I'm going to try it out because I'd like my tildagon to have real time. Even without internet or GPS.
It is this breakout garden board from Pimoroni: https://shop.pimoroni.com/products/rv3028-real-time-clock-rtc-breakout
I have a 4 unit lipoly that I used for powering my bike that comes from the same range as the existing tildagon battery that I threw away right at the start of this journal.
Cut that out of bike prototype and plug it into the tildagon. It's still mostly charged. The charge LED on the back board goes from flashing red to solid red. and I can now disconnect my USB cable and the tildagon stays awake. aka how it should have been all along...
This battery is almost as big as the tildagon itself! Probably the right place is on the back of the back board. In bike prototype I had it cable-tied on. Or maybe I have the right kind of tape here to attach it.
I have three breakouts I want to use. Time for protoboard building. The breakout garden connectors I have have too short pins for me to get my verowire pencil to stay on, so I'll do solder traces instead, for everything except the interrupt pins, which I don't need today. Later, I can wire them with regular wires I guess, point to point.
here's a video of what I want to do https://www.youtube.com/watch?v=kROaQZOYNIw
That was a bit frustrating but its done and now I have three breakgarden i2c devices connected into the same hexpansion port and my code from yesterday for talking to co2 sensor and for talking to gps is working without modification.
The NMEA messages that come out of the GPS are padded with \n when there is nothing more in the buffer, so I made the code detect that and pause polling the GPS for more data for a longer period - apart from at the start, there won't be any more data for almost a second once this happens, so a third of a second delay seems to be ok. I'm not trying to get sub-second accuracy.
This is only for FOSDEM starting tomorrow with an emphasis on collecting raw data for processing later. So effort on driving the sensors and logging to a file. with whatever random UI happens on the way.
Fairly straight forward to make an ugly looking app that logs one json dict per line, which is a format I've found easy to process elsewhere.
Now time to take it a walk around the neighbourhood.
3 people recognised tildagon, plenty of people asked about it
I ran data logger for a data, grabbed the logs. Then day 2, ran a modified data logger which captured readings much faster as I realised while walking round that I could walk quite far in a minute.
On the train back, playing with visualization of the GPS vs access point readings. The data doesn't give me quite the distance-over-space view I was hoping for but there is plenty to play with in preparation for doing this again some how.
Using breakout garden connectors on a badge is a terrible thing to do - the breakouts kept popping out. I ended up taping them in place with electrical tape, and then they just came loose and stopped working sometimes, rather than falling on the ground and me hoping I noticed.
I was vaguely aware of aiorepl in micropython and vaguely annoyed by no repl while the tildagon OS is running, instead having to crash out to get a reply.
Someone else raised a similar complaint on IRC and opened issue #252, which turned out to be an hours work and a couple of lines in my PR 254 to make aiorepl run alongside the rest of the tildagon OS.
offline vacation
Someones got an app called exploding fist which is failing at startup. But the firmware doesn't give a good stack trace in that case. Modify my PR to make a better console stacktrace, something I wanted to do already anyway, and which could be a small PR?
looks like mpremote and other tools get interfered with by the aiorepl. but not in a super clean way: mpremote sometimes works for me, sometimes doesn't. probably the firmware should be stopped when using those tools because they can all print to the serial console which those tools probably expect to be clean. PR #261 from someone else adds a setup option to switch to more traditional repl.
rename sequencer to scripter - that sounds a bit more like a scripting language rather than a musical instrument
get mypy running, with weird convolutions to work with the sim/ cpython environment and the differences with micropython
fix a bunch of type errors
start a bit of breaking the main app.py into modules, with more confidence now there's some type checking
lots of messing around trying to get it to build in my dirty build tree. classic build system problems of not having a decent clean target. eventually cleared away micropython/ submodule and reinitialized it, and repatched it, and forget to do the sub-sub-modules a few times. but it's done now.
now the buttons still work after a soft reboot! which makes mpremote playing a bit easier as I can more easily reboot from there repeatedly.
What should this look like on startup. Right now it goes into run mode automatically. But now I think it should go into edit mode automatically, with a very simple pre-loaded script, more simple than what I have now. (the existing pre-loaded script was because I didn't want to be choosing options the whole time and for some steps I didn't/don't have the functionality to input the steps(!) but the time for that being acceptable is past)
I pulled all the steps into their own source files, and put the corresponding UIs in those same files. That doesn't completely remove all step references from the main application but it goes a long way to doing so.
I've been developing in the last week in the simulator (which runs on cPython) and pushing on mypy, knowing that the type annotation syntax isn't fully supported in micropython. So now it is time to discover what I broke and how to fix it...
AttributeError: 'module' object has no attribute 'python_implementation' - ha ha I assumed this would exist on all platforms?
... and turns out that was an easy fix and the only problem I encountered!
Now there's two bugs I want to work on: stack based return to what we were doing before when a when-block triggers a new code path. (so that my default when-program-starts do-forever flash leds program keeps running after being interrupted by a badge upright when); and editor consistency so that blocks are deleted in their entirety and the program remains always consistent (and maybe I should do a bunch of asserts around that?
... Getting a stack in place was not very hard. And less hard to approach than the UI stuff which I am fundamentally not fond of.
To get started on the next bit, first add assertions before/after the delete, so I can see the program crash immediately when I delete something not permitted. Add a new assertion that When-blocks can only appear at the top level, not inside another block.
Next, I've made it: not delete anything when pressing delete on end steps, and delete the whole block when pressing delete on a BlockStep.
The next thing is making When-steps be inserted always at the end, as a new top level block, no matter where the cursor is.
There's potential for getting a release out today that is actually tryable by other people. If I don't fall asleep.
Now it's time to do the boring work of making an insert UI for every step type that I have.
With that done, get release 0.0.2 onto the app store and post about it in badge IRC.
Jonty appeared right after that with a mostly-working wasm badge emulator in-browser. So spend the rest of the evening fiddlign with that, including learning about emscripten concurrency primitives and how micropython wasn't yielding properly, so downloads weren't working, which meant the app store wasn't working. Now I've got my scripter app running in there. Though it crashes if using IMU steps because there's no IMU. If I delete that step from the default program, it runs ok. Although I discovered a new bug about where the cursor goes when you delete the last block and get an assertion failure.
Slightly sleepless at 03:30, fixing a couple of UI things: Don't show delete option on non-deletables (which right now is only End Steps) ; Delete step might delete the final step of the script that we might be left pointing at. In that case, move the cursor up to the new end of script.
A remaining UI problem is inserting a new step before the first step (which is kinda the obvious "Insert step" for a new user. That can insert invalid steps immediately and cause a malformed script assertion failure. That can happen when focused on any When block. Maybe "Insert Step" should change into two options, or maybe the list of available steps should dynamically change? Pragmatically I need to pick one arbitrarily now so I don't get UI crashes.
Put out some more releases (0.0.3, 0.0.4, 0.0.5) with the above and some package/release fiddling.
Wrote a keyboard driver and put that online, that takes keystroke from the usb serial console and turns them into keyboard events. That's so you can use your laptop as a keyboard, instead of the new official hexpansion keyboard.
I was wondering when the app store changes its install code (which is used for entering into the tildagon app store app, but also app store URLs in web browsers. It is changed on every release. That is frustrating - it means I can't persistently link to either of my apps!
I made a PR to make the app store use keyboard events for code input in addition to the side buttons. https://github.com/emfcamp/badge-2024-software/pull/327 - that means you can cut and paste a code from the web page into a terminal attached to my USBSerial kbd app, but also probably fixes a bug with input from the Official Tildagon Keyboard hexpansion.
Months ago I got a time of flight 8x8 pixel sensor on a pimoroni breakout garden board, intending to attach it to tildagon. I finally wired it in and can see it on the i2c bus. Now there's a lot of driver messing to happen before I can get anything from it.
Its jumpered onto one of my protohex PCBs. I can say:
>>> from machine import I2C >>> i = I2C(2) >>> i.scan() [41] >>> 0x29 41
and there it is!
Next day... now working on getting the driver from pimoroni's micropython fork into the tildagon firmware. Which involves cmake. and kinda feels like my early linux days of downloading stuff by source and messing round compiling it. Kinda interesting, also kinda horrible. So far the big deal is: getting the paths all wired up. porting to different i2c system, the tildagon hexpansion aware one.
... finally got it compiling. it crashes with ENOENT when I create an object, but I at least have got as far as it being importable in micropython... realised I hadn't copied the firmware blob on for the board itself.
Lots of debugging. Its hanging at part of the initialization, with an error that seems like this https://community.st.com/t5/imaging-sensors/vl53l5-init-stalls-at-get-offset-nvm-data/td-p/97439 so maybe that's something for me to investigate...
And another day start... found another forum post on this https://qa-community.st.com/imaging-sensors-49/vl53l5cx-initialization-fails-with-uld-driver-v1-3-6-16514?tid=16514&fid=49. Also not the problem but it did encourage me to think if I had implemented the send correctly. Which I had not - I was sending one byte too many due to a brainfart last night. So now it can talk to the sensor and is return 64 bytes, the first 16 of which change and the rest are 0, into python. So I suspect that it is working in 4x4 mode when I want 8x8 mode.
There's a function to switch to 8x8. Call that.
These results don't look right from an eyeballing of the array. Though I'll visualize them too. Perhaps there's something not right in the decoder that loads and turns them into a C structure. If they're in mm, it sounds like it things loads of stuff is around 20cm away. which is free space right now...
got it imaging - its only reading in at a frames per second - i wonder what takes the time. its loading 1kb of data on each frame over i2c which is a lot more than the 128 bytes needed for raw 2-byte x 64 values. there's some opportunity for turning this sort of stuff off in various places so maybe that's a possibility? also maybe some of the i2c changes I did yesterday while hacking probably slow things down and I can unwind them.
Turned off loads of data - reading size is under 200 bytes now. And called set_ranging_frequency_hz(10) to get it to scan faster. Now it makes a nice animated on-screen display. Play with the colouring a bit.
Some questions on IRC over a day about how apps might be installed on a flopagon and how to get the code imported right. I had a fiddle with them and seems like theres some weird behaviour around the flopagon file system wrt imports (rather than normal visibility of files). Ended up having a couple of flopagons put in the post to me here in Berlin (from UK?). I hope they'll arrive OK and should be fun to play with.