-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timer support? #15
Comments
It's certainly possible. I'm torn between using
I'm somewhat in favour of the latter, since it's a little easier to reason about and compartmentalise than relying on one single
|
Personally, I would opt for no. 2, with the capability to cancel. That would allow different use cases:
My immediate use case would be the second, with cancelling before the alarm goes off ... based on my SHIFT key use case. Implementation-wise maybe we can use coroutines for running a socket-based sleep using luasocket, and then dispatch from there? |
It would be beneficial if a timer library (module) could be used not only on the Keybow firmware (Pi), but also on a host system, to ease development and testing. |
Related and unrelated, but if I understand the answer to the following, I could have an opinion on timer... How many instance of Lua are running in KeyBow? If I press key 00 and without releasing key 00 and next press key 01, does the treatment of key 01 wait for the end of the treatment of key 00... or does the Lua treatment of key 01 start as soon as pressed, even if key 00 "macro" is still running. If I press repeatedly on key 00, very fast, faster that the time it take to process key 00 in Lua, does the new call wait and is queued, or does the second press (or release) is send in parallel with previous treatement. I can imagine things being very messy if the Lua code is more complex than a simple mapping, and start to take time, or use state information for various behaviour. It become a very dangerous place to write code with many things running in parallel. I think I will write some test script to see in practice how it seems to behave. Thanks. |
You can see how Keybow key handling work from the file Everything in perfect sequence; that's why my multibow can be kept simple in places: simple key event handling one after the other, even when pressing multiple keys. Pressing and releasing the same key are two unrelated events. If you managed to press and release a key in less than 1ms, the current Keybow software would just miss some key state changes, but nothing will pile up. Sweet and simple, very straightforward. |
I've learned the hard way to be very wary of threads, so Keybow is- indeed- sweet and simple. Any cooperative multitasking would be managed in the same loop that scans input keys and dispatches events, and any long-running process (whether it's a timer event or a key press/release) will block further input until it completes. Depending on what overhead it might introduce I think the most flexible approach is probably to have the What you put in this function would then handle the dispatching of timers in whichever way you see fit. |
Okay I've added a call to If the first attempt to call this function fails (ie it does not exist in your lua file), it'll ignore it for future attempts. This is because I was encountering a segfault with rapid successive checks for an existing function in lua. Since I only need to check it once, though, this seemed like the easiest way to accomplish that without extra API surface. This function is passed the time in milliseconds since the epoch- could probably adjust this to be script runtime for sanity. In fact- 9657447 |
If you want to play with the timer, you can grab a zip of the media-keys branch, or just replace your |
I assume the timer can also allow a delayed action similar to |
Somehow I don't see how to calculate a suitable alarm/trigger time in ms when Lua has no function to get the current time in ms, but only with seconds resolution. So I cannot calculate a sensible now+500ms to repeat a key, but I need a time in ms in order to compare against the current time in ms for every tick(). Did I overlook something? Note that os.clock() * 1000 doesn't work in this case, because it's too coarse. |
Hm, an ugly hack would be to store away the time given to tick() as the current time for calculating relative alarm offsets... 🤔 And from there on, alarm handling would use a priority queue. From what in I've seen, Luaists tend to misuse tables as priority queues... 😳 |
🎉 branch feature/time of multibow now has a fully working timer framework on top of This feature branch of Multibow now supports:
When do you plan to release your |
Sifting through Keybow's C code, I now notice another peculiar thing: A The bottom line here might be that I need to monkey-patch some of Keybow's (intermediate) lua functions related to tapping keys, text, and modifiers in order to make them useful again in combination with timers: that is, these functions need to be monkey-patched in order to add their args to a queue which is then processed piecemeal-wise in the |
Sorry for not keeping my eye on this- I’ve been super busy with, admittedly, somehow more exciting stuff! If you’ve got any suggestions for what I could change in the code to make your life easier, I’m all ears. Unfortunately the HID report is set up to send on any key change to avoid having the user manually call a “send HID report” function from Lua, but I don’t believe there’s any reason why we couldn’t make this an option for more advanced use-cases so we can avoid some of the delays. That said- I’m not sure if Shift and a key can be sent as part of the same HID report and not result in some kind of race condition. Worth exploring though! The other killer is that- while it’s entirely possible -I really want to avoid introducing any threading here. Since any typed sentence is likely to be blocking anyway I don’t think there would be a benefit to threading and queuing HID output- sadly a choppy timer (which could very easily miss scheduled events and be prone to being inacccurate) is probably a better solution than timer events firing mid sentence and causing weird side-effects. I’m happy to release this ASAP (in practise sometime this coming week) if you’re happy with how it works so far, and we can see how to improve it from there. I’ve got a sheaf of design documents and specs on my desk for a MIDI controller which will probably need many of the same features- so it’s tike well spent. Awesome work- by the way! |
While not ready yet, I'm slowly working on asnchronuous and cooperative key and modifier functions in Lua. This way, the existing API including its delays can be kept as is, and the new keybow asnchronuous functions on top would experience jitters, but would be okay with that. I'm trying the old route of cooperative tasking, so no threading. That means that releasing your designated design as is looks great. If necessary, later improvements can be made when I know better what small set of additional Keybow API Lua-C functions without delay would be benefiting, as I"m now breaking up those things requiring delays to be done in separate ticks. If that works out as expected, I can even monkey-patch the pure Lua key functions to be rerouted to the cooperatively ticking ones... I'm astonished that 1ms delays are even already enough, but would have expected needing larger delays. Anyway, my idea is to keep the API as is, and then spread longer key operations over multiple ticks in the Multibow layer. This also avoids the critical timing parts you mention. And it doesn't change things for people using and programming Keybow as originally designed. Multibow is a crazy expedition in running a full blown OS with a scripting layer on top inside a USB keyboard. We're so decadent here, we're just the perfect example to those extremists on YouTube how rotten we are. manic laughter |
Serial IO, Note: The latter requires a new initrd to mount |
I've had success with writing to |
For multibow, I've now implemented sending USB keystroke piecemeal-wise one after another with each Additionally, I've designed a new and hopefully cool keystroke sequence API that is heavily inspired by "chaining" as found in busted's luassert, et cetera. This API schedules the keystrokes to be send in the tick background (no multithreading). So you can now write key sequences as:
Need ^ENTER instead?
Want to repeat yourself?
Okay, let's add a final ENTER, but we want to do it in a single chain, ensuring that we repeat only tapping the "keybow" text, but not the ENTER:
Insert delays:
|
@Gadgetoid Would it be possible to officially release a new (0.3?) version of the Keybow firmware including the new |
@Gadgetoid ping ... Any chance of a release? |
@Gadgetoid I'm slowly loosing any faith in Pimoroni now. I understand that the company has a lot of projects going on simultaneously, and that this doesn't seem to be a high priority project. That's fine. But since I've invested quite some time of mine to actually make good use of the feature I asked for, I'm now really p.o. (is there an official Unicode glyph for this yet?) with no official release from Pimoroni even months after a poc was done and I showed that it is useful, so other buyers of Keybow hardware can use my software in which they expressed interest. I don't have the resources to keep and maintain a fork of the base firmware, so this looks like I'm now flogging the dead Pimoroni horse here. Next time, I will be more reluctant to recommend any hardware and its software to anyone, as this is a game of hit and miss, but far from at least a 50:50. I consider myself burned enough here and even consider archiving my own project based on a dead feature that Pimoroni doesn't bring onto master releases. I also really consider to close this issue if there's still no reaction from Pimoroni, as they sell the hardware and then quickly loose interest in the software. This is now no different from any cheap Chinese seller throwing their hardware on the market, then walking away. Because it's "open source". |
I'm sorry to let you down. While it's not an excuse, I think it cannot be stressed enough that when you say "they" you're referring to just "me." Pimoroni isn't a huge corporation with dozens of engineers- I'm almost singularly responsible for 117 public repositories and involved in many more projects in the pipeline. Couple this with the fact I've had a new baby since the 15th of March and have also been more than a little distracted by our 32blit project- well it adds up to things like this, while very much still being of interest, taking a not insignificant amount of time to get 'round to. None of this, however, excuses not getting back to you for three months and for that I'm sorry. Since it's just me I have a practise of leaving PRs (usually finished code) languishing for a couple of weeks so I can look over it again with fresh eyes and catch any silly errors or omissions. Okay- for not an excuse that sure was a lot of excuses. I'm looking into getting this fix merged and into a release (and not just because of Keybow Mini!) now. |
Hi folks! Reading up about Keybow/Multibow (🤯❗), I'm trying to figure out what is missing for this ticket to be closed. The @thediveo @Gadgetoid So -- with much respect for your diligence in creating these niche software projects (and yet very exciting for some, like me) -- what's the status of this? Is there anything you need help with? |
@jezdez thank you! Judging by the message on the multibow GitHub repository it looks like faith was, indeed, lost and it has been abandoned/archived - https://github.com/TheDiveO/multibow A shame! It's really cool to see third-party software projects based around our projects, and I'm really sad to see it die by the wayside- especially as, for better or worse, I'm largely at fault for dropping the ball here (circumstances notwithstanding). Maybe @thediveo will return in time? Or another maintainer will pick up this project. |
I would like to implement (macro) key repeat and long key presses. Any chance for some kind of timer support?
The text was updated successfully, but these errors were encountered: