CommonSense: matrix LCR meter with a HID interface
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Integrated green wires to
Speaking of which - insertion force seems to be significantly more than 1 kg, and this worries me.
Can't find exact specs for triomates mating force anywhere in the internet - it may be 5 kg easily. On a 16-pin socket. And there will be 30 pins in total.
May be something like http://suddendocs.samtec.com/catalog_english/bcs.pdf + http://suddendocs.samtec.com/catalog_english/tsw_th.pdf - yeah, standard pin headers - would be better. samtec promises about 120g/pin. Which is 3kg.
Or go 1.27mm pitch? http://suddendocs.samtec.com/catalog_english/slm_th.pdf + http://suddendocs.samtec.com/catalog_english/dwm.pdf for example?
Won't make things worse - traces are running even closer than that for extended periods of time. Mating/unmating force will be significantly lower. Pins will be a bit more fragile though.
Will try to trace beamspring adapter tomorrow - to see how it should look.
87x15mm - had to make the PCB a bit taller to accomodate the triomate connector.Speaking of which - insertion force seems to be significantly more than 1 kg, and this worries me.
Can't find exact specs for triomates mating force anywhere in the internet - it may be 5 kg easily. On a 16-pin socket. And there will be 30 pins in total.
May be something like http://suddendocs.samtec.com/catalog_english/bcs.pdf + http://suddendocs.samtec.com/catalog_english/tsw_th.pdf - yeah, standard pin headers - would be better. samtec promises about 120g/pin. Which is 3kg.
Or go 1.27mm pitch? http://suddendocs.samtec.com/catalog_english/slm_th.pdf + http://suddendocs.samtec.com/catalog_english/dwm.pdf for example?
Won't make things worse - traces are running even closer than that for extended periods of time. Mating/unmating force will be significantly lower. Pins will be a bit more fragile though.
Will try to trace beamspring adapter tomorrow - to see how it should look.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
http://www.descent2.com/goodies/fonts/ - 10 years ago someone made the font (caps only, unfortunately).emdude wrote: ↑Haha, I love that logo! That looks like the font used for Descent's title!
It is my favorite font (after comic sans kekekeke)!
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Turns out I was doing it all in mirror image all that time.
Thanks for cypress' flexibility it's not a huge problem - but still. If mirrored, sense lines will cross USB data lines, which are noisy.
But then again, the way it's laid out now is perfect for displaywriter (and normal beamspring if there's enough vertical space). And mounting 90 degrees to the board, chip towards the backplate. Drive lines run across USB and power, sense lines away from them.
In other news, attempt to change connector to 0.050" pitch removed all traces from the board, so I might as well re-route it correctly
those 0.050" connectors have per pin: mating force 1N max, retaining force 0.12N min. So it appeals more and more to me to move to this form-factor. At least for phase 2 MF. 400 grams retaining force is a nice figure, very low damage risk.
Pictures a bit later - rerouting 50+ traces takes time. Surprisingly meditative activity, I found that I don't even mind redoing.
Thanks for cypress' flexibility it's not a huge problem - but still. If mirrored, sense lines will cross USB data lines, which are noisy.
But then again, the way it's laid out now is perfect for displaywriter (and normal beamspring if there's enough vertical space). And mounting 90 degrees to the board, chip towards the backplate. Drive lines run across USB and power, sense lines away from them.
In other news, attempt to change connector to 0.050" pitch removed all traces from the board, so I might as well re-route it correctly
those 0.050" connectors have per pin: mating force 1N max, retaining force 0.12N min. So it appeals more and more to me to move to this form-factor. At least for phase 2 MF. 400 grams retaining force is a nice figure, very low damage risk.
Pictures a bit later - rerouting 50+ traces takes time. Surprisingly meditative activity, I found that I don't even mind redoing.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Routed 3 versions, to compare. Core is the same, connector to outside world is different. "GND" is a standard 2-pin header, 6-pin headers are also standard 0.1" pitch 2x3pin.
IBM 30 pin, 4.78x0.82": mini-xwhatsit-compatible 0.1" pitch, 3.43x0.57": Proposed 0.05" pitch, 1.75x0.57": Had to develop a compact logo variant for the 0.05" version. Prefer to go ahead with 0.05" version because it can be put anywhere, and if ribbon is needed it will be just 1.7" wide. But for MF phase 1 special PCB version can be designed, which will be a drop-in mini-xwhatsit replacement. Easy to do, just LOTS of empty space on the board.
IBM 30 pin, 4.78x0.82": mini-xwhatsit-compatible 0.1" pitch, 3.43x0.57": Proposed 0.05" pitch, 1.75x0.57": Had to develop a compact logo variant for the 0.05" version. Prefer to go ahead with 0.05" version because it can be put anywhere, and if ribbon is needed it will be just 1.7" wide. But for MF phase 1 special PCB version can be designed, which will be a drop-in mini-xwhatsit replacement. Easy to do, just LOTS of empty space on the board.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Turns out shielding is useful, after all.
This is 3 adjacent columns with shielding removed. This is 3 adjacent columns, same board, shielding intact. Shielding prevents charge sapping by an adjacent line. Supposed to be a Good Thing, makes for more consistent readouts. But the price is great - half of the charge carriers sapped by the ground (another interpretation would be "but the resulting capacitor is twice as large and voltage achieved is much lower".
One thing to note is that in second picture there's still 2 foot of unshielded ribbon cable between PCB and controller, and the effect is not nearly as drastic. Can't really explain that. I think it favors "charge carriers escape" theory - shielding removed is really close to the flipper. But the logic behind this explanation is pretty poor.
This is 3 adjacent columns with shielding removed. This is 3 adjacent columns, same board, shielding intact. Shielding prevents charge sapping by an adjacent line. Supposed to be a Good Thing, makes for more consistent readouts. But the price is great - half of the charge carriers sapped by the ground (another interpretation would be "but the resulting capacitor is twice as large and voltage achieved is much lower".
One thing to note is that in second picture there's still 2 foot of unshielded ribbon cable between PCB and controller, and the effect is not nearly as drastic. Can't really explain that. I think it favors "charge carriers escape" theory - shielding removed is really close to the flipper. But the logic behind this explanation is pretty poor.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Got a configurable delay between events - foundation for the macro engine which will need all this.
Ever hated^Wwanted that office 2013 typing animation systemwide? You got it! (first keypress is reported immediately, don't you worry. This delay is there so slower system can still figure out keypress order reliably. Think xwhatsit' solenoid delay. You can now, for example, sync keypresses reported to system with solenoid clicks.)
Max. delay 65535ms - that's right, tad more than a minute.
Interesting problem cropped up - if you type too fast, autorepeat kicks in
Also probably need beefier USB scancode buffer - physical to USB scancodes are translated almost immediately, but USB events are dequeued slowly, so buffer needs to be pretty large.
Philosophical question - if you have 100ms between keys, and macro wants 30ms delay between events - what happens?
First event, naturally, will be output right away. But what happens then?
Ever hated^Wwanted that office 2013 typing animation systemwide? You got it! (first keypress is reported immediately, don't you worry. This delay is there so slower system can still figure out keypress order reliably. Think xwhatsit' solenoid delay. You can now, for example, sync keypresses reported to system with solenoid clicks.)
Max. delay 65535ms - that's right, tad more than a minute.
Interesting problem cropped up - if you type too fast, autorepeat kicks in
Also probably need beefier USB scancode buffer - physical to USB scancodes are translated almost immediately, but USB events are dequeued slowly, so buffer needs to be pretty large.
Philosophical question - if you have 100ms between keys, and macro wants 30ms delay between events - what happens?
First event, naturally, will be output right away. But what happens then?
- Techno Trousers
- 100,000,000 actuations
- Location: California
- Main keyboard: IBM Model F-122
- Main mouse: Mionix Naos
- Favorite switch: Capacitive Buckling Spring (Model F)
- DT Pro Member: 0159
Interesting! So what happens if you kick off a 10 second macro, and immediately begin typing? Will it be able to queue up all of your post-macro keystrokes and send them once the macro has finished playing?
The answer to your philosophical question, I think, is that the defined delay between macro events should be added to whatever baked-in delay is needed per keystroke (basically that defines the minimum). So in your example of a 100ms per key delay, specifying 30ms between events would translate to a 130ms delay.
The answer to your philosophical question, I think, is that the defined delay between macro events should be added to whatever baked-in delay is needed per keystroke (basically that defines the minimum). So in your example of a 100ms per key delay, specifying 30ms between events would translate to a 130ms delay.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
"Beefier USB scancode buffers" refers exactly to this situation.Techno Trousers wrote: ↑Interesting! So what happens if you kick off a 10 second macro, and immediately begin typing? Will it be able to queue up all of your post-macro keystrokes and send them once the macro has finished playing?
what if there are 3 events?Techno Trousers wrote: ↑The answer to your philosophical question, I think, is that the defined delay between macro events should be added to whatever baked-in delay is needed per keystroke (basically that defines the minimum). So in your example of a 100ms per key delay, specifying 30ms between events would translate to a 130ms delay.
Easiest thing to do (because I'm already doing it, or at least USB code buffer is set up that way) - macro populates the queue with time marks in the future. USB events are <=now are shipped to host, one by one. This happens every millisecond, with cooldown timer. So A[30ms]B[30ms]C with 50ms delay will translate to A[50ms]B[50ms]C - as will A[30ms]B[60ms]C. Not that I worry much about all this in practice - if you're inserting delays it's because something can't keep up with you, and you actually want to make things _slower_. Which by definition means longer than minimum delay you have in the system.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Added expansion header support.
For now only "solenoid" and "Lock LEDs" modes. "X plus switch" is not hard to add.
Only checked by scope, because I don't have any hardware.
xwhatsit pauses scanning for the duration of solenoid pulse. I currently don't - want to actually see what happens. I tried to separate exp. header traces from sense line traces as far as I could, and also I poured ground around those traces (and USB traces too) - but I'm not sure that will be enough. There's band pass filter too - but if even that won't be enough.. well.. can pause scanning too, I guess.
Speaking of expansion header. I don't like current connector layout - plugging into controller upside down will result in polarity reversal and most probably fiery death of the chips on the solenoid board.
On a CommonSense prototype the ground moved to pin 3 (pins are numbered 12-34-56).
This will made existing solenoid boards incompatible (pin 3 is not used in original solenoid boards), but more likely to survive plugging upside down. It looks like there's an easy fix - daughterboards' wires are actually soldered to it, not connected via the header. Just swap 2 wires and you're good to go.
Probably need to vote on that though. This is possibly annoying change, but since we're going solderless we should make the system more user-proof. Another way do do this is to key the socket - like internal USB connectors do. But it's more expensive at our scale.
For now only "solenoid" and "Lock LEDs" modes. "X plus switch" is not hard to add.
Only checked by scope, because I don't have any hardware.
xwhatsit pauses scanning for the duration of solenoid pulse. I currently don't - want to actually see what happens. I tried to separate exp. header traces from sense line traces as far as I could, and also I poured ground around those traces (and USB traces too) - but I'm not sure that will be enough. There's band pass filter too - but if even that won't be enough.. well.. can pause scanning too, I guess.
Speaking of expansion header. I don't like current connector layout - plugging into controller upside down will result in polarity reversal and most probably fiery death of the chips on the solenoid board.
On a CommonSense prototype the ground moved to pin 3 (pins are numbered 12-34-56).
This will made existing solenoid boards incompatible (pin 3 is not used in original solenoid boards), but more likely to survive plugging upside down. It looks like there's an easy fix - daughterboards' wires are actually soldered to it, not connected via the header. Just swap 2 wires and you're good to go.
Probably need to vote on that though. This is possibly annoying change, but since we're going solderless we should make the system more user-proof. Another way do do this is to key the socket - like internal USB connectors do. But it's more expensive at our scale.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Looked at PCB assembly prices. Looks like it will cost more than parts and PCB combined.
Changed chip to TQFP - those are easier to solder. But twice as much pins so assembly is even more expensive. But since it looks like I'll be assembling those anyway- number of pins doesn't matter.
Also figured out why MF logo threw an error with oshpark's gerber parser. 63-point polygons - oshpark cannot into those.
Changed chip to TQFP - those are easier to solder. But twice as much pins so assembly is even more expensive. But since it looks like I'll be assembling those anyway- number of pins doesn't matter.
Also figured out why MF logo threw an error with oshpark's gerber parser. 63-point polygons - oshpark cannot into those.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
After talking with __red__ yesterday, something clicked and I wrote macro engine.
Rudimentary. No GUI yet so not yet usable.
But still - right now pressing F24 on my keyboard presses LShift-A.
And it's more advanced than anything around - it's non-blocking. Means "key sequence is queued the moment you press the button - with timings".
This allows, in theory, for interesting ways to shoot yourself into foot. Let's see if it actually leads to someone doing it.
But first I need to write a GUI for it. And import/export into a text file (layouts are probably going that way too - instead of codes there will probably be key names in layout file) - though I need to figure out how to do text parsing in Qt in a non-ugly way.
Rudimentary. No GUI yet so not yet usable.
But still - right now pressing F24 on my keyboard presses LShift-A.
And it's more advanced than anything around - it's non-blocking. Means "key sequence is queued the moment you press the button - with timings".
This allows, in theory, for interesting ways to shoot yourself into foot. Let's see if it actually leads to someone doing it.
But first I need to write a GUI for it. And import/export into a text file (layouts are probably going that way too - instead of codes there will probably be key names in layout file) - though I need to figure out how to do text parsing in Qt in a non-ugly way.
- vvp
- Main keyboard: Katy/K84CS
- Main mouse: symetric 5-buttons + wheel
- Favorite switch: Cherry MX
- DT Pro Member: -
Chrisandreae's firmware has at most 6 interpreted programs which can run inside the keyboard and produce precisely timed keyboard and mouse events which are merged with the actual key press/release events from the keyboard matrix scan. The language supports variables, branching, loops and subroutines. There are some quirks though.DMA wrote: ↑ And it's more advanced than anything around - it's non-blocking. Means "key sequence is queued the moment you press the button - with timings".
That is besides the standard macros/remaps as on Kinesis Advantage.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Hehe. The art of trolling it's simple.vvp wrote: ↑Chrisandreae's firmware has at most 6 interpreted programs which can run inside the keyboard and produce precisely timed keyboard and mouse events which are merged with the actual key press/release events from the keyboard matrix scan. The language supports variables, branching, loops and subroutines. There are some quirks though.DMA wrote: ↑ And it's more advanced than anything around - it's non-blocking. Means "key sequence is queued the moment you press the button - with timings".
That is besides the standard macros/remaps as on Kinesis Advantage.
If I didn't write "more advanced than anything around" - would still be oblivious to existence of this.
Nice idea, my first thought was "I should actually port this to cypress and extend instead of mucking with whole thing myself - less maintenance, yay" - but then I noticed it's AVR-only. AVR sucks. It sucks so much there's no point trying.
..and still. Looking into code.. looks like that macros are still played in realtime, not "enqueue and forget". But at least delays are not blocking - that's more than can be said for most firmwares around
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Productive day.
Tap macros - "on keyUp, if quick enough and no other keys pressed between keyDown and keyUp". Intended to bind a macro to modifier keys, without losing the key. Don't eat the key (plain keyUp and keyDown macro eat the key they're bound to).
GUI is not even started
Tap macros - "on keyUp, if quick enough and no other keys pressed between keyDown and keyUp". Intended to bind a macro to modifier keys, without losing the key. Don't eat the key (plain keyUp and keyDown macro eat the key they're bound to).
GUI is not even started
- Techno Trousers
- 100,000,000 actuations
- Location: California
- Main keyboard: IBM Model F-122
- Main mouse: Mionix Naos
- Favorite switch: Capacitive Buckling Spring (Model F)
- DT Pro Member: 0159
I'm loving all your progress, DMA!
- Ray
- Location: Germany
- Main mouse: touchpad
- DT Pro Member: -
These kinds of tap-macros are kind of nasty to provide. On TMK 90% of the time the default behaviour was next to perfect to what I could have (still not what I wanted, because what I wanted was a "do what I think right now"-solution), but in some corner-cases I just needed something else.
example: I have a tap->backspace/hold->leftshift key on my keyboard. Hasu's default for that stuff works really good for that and there even is a key-repeat for backspace if I tap once and hold after. I only need that on windows, where cntrl-backspace does not reliably delete a whole word.
But here comes the question: should it press shift always when the key is pressed and release shift just before sending the backspace? In my case yes, because that's what you need to do fast shift+clicks with your mouse. But there's other cases where that kind of behaviour would be annoying I guess.
What I want to say: There is no absolutely correct way of implementing a default here. Don't try to find one right now, try to implement a macro-engine that is capable of doing anything and let the community figure out what they want in each individual case. Also better documentation is more important here than better defaults. If we have good documentation, we can work on good defaults together.
example: I have a tap->backspace/hold->leftshift key on my keyboard. Hasu's default for that stuff works really good for that and there even is a key-repeat for backspace if I tap once and hold after. I only need that on windows, where cntrl-backspace does not reliably delete a whole word.
But here comes the question: should it press shift always when the key is pressed and release shift just before sending the backspace? In my case yes, because that's what you need to do fast shift+clicks with your mouse. But there's other cases where that kind of behaviour would be annoying I guess.
What I want to say: There is no absolutely correct way of implementing a default here. Don't try to find one right now, try to implement a macro-engine that is capable of doing anything and let the community figure out what they want in each individual case. Also better documentation is more important here than better defaults. If we have good documentation, we can work on good defaults together.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
This version is even nastier than you think. No autorepeat - because tap, by definition, is a _short_ event. In your case, BkSp will fire on key release, once (how long it will be down is configurable). No double/triple/etc taps either, because then I'll need to delay scancode lookup till I'm sure I've caught all the taps - and let me tell you, you don't want this to happen*. Fuck it, use AHK or another hotkey/shortcut manager if you want something like that. There's something to do on keypress (send this keycode or enqueue a sequence _instead_), key release (send this keycode up, or enqueue a sequence _instead_), or tap (If I figure out it was actually a tap - i.e. they key released is the one that was previously pressed, and it happened fast enough - enqueue a sequence _in_addition_ to whatever is happening).Ray wrote: ↑These kinds of tap-macros are kind of nasty to provide. On TMK 90% of the time the default behaviour was next to perfect to what I could have (still not what I wanted, because what I wanted was a "do what I think right now"-solution), but in some corner-cases I just needed something else.
*) because then I would only report scancode when the _next_ key is pressed or tap timeout expired. Which means half a second (well, may be 300ms, but hardly less) delay. Which will basically make keyboard unusable.
That depends. If you want it not to - you'll pay with the aforementioned delay. As for shift-clicks - it's a leeeeettle bit more interesting question. Your keyboard doesn't know about your mouse. Only OS knows. So from OS' standpoint it would not be a tap, while from keyboard standpoint it would probably be one (depends on the duration).Ray wrote: ↑But here comes the question: should it press shift always when the key is pressed and release shift just before sending the backspace?
Sorry, not going to do that. I value my sanity too much. I've spent 2 months pondering the philosophical questions (like "what if you bind a macro to "G+H"?" and "what if you bind Alt-F and try to output "Ctrl-F"?" and "what to do with modifiers being changed as the macro is playing?") and _thoroughly_ sick of it.Ray wrote: ↑try to implement a macro-engine that is capable of doing anything
It may just click one day and I'll suddenly understand how to do this. But that satori moment is highly unlikely, see your "shift-clicks and taps" question.
I was thinking of using tmk_core (or kiibohd - you know, that serial console thing is ATTRACTIVE) to not implement this whole macro shebang - but found that busy-wait delays are used there, which would not play well with my interrupt-driven scanning machinery. And I can't just disable interrupts - this would drive scan rate into the ground. 10ms interval when playing tmk macro means there's no matrix scanning for 10x milliseconds. I don't think it's a great idea to put scanning on handbrake because you want to play a macro.
- vvp
- Main keyboard: Katy/K84CS
- Main mouse: symetric 5-buttons + wheel
- Favorite switch: Cherry MX
- DT Pro Member: -
Here is how mine branch of Chris' firmware works:DMA wrote: ↑Sorry, not going to do that. I value my sanity too much. I've spent 2 months pondering the philosophical questions (like "what if you bind a macro to "G+H"?" and "what if you bind Alt-F and try to output "Ctrl-F"?" and "what to do with modifiers being changed as the macro is playing?") and _thoroughly_ sick of it.Ray wrote: ↑try to implement a macro-engine that is capable of doing anything
- "G+H" bound to an exclusive macro will emit: G-down, G-up, ... <macroSequenceAsDefined-AllKeyMatrixStateHidden>, and if G is still pressed at this time then G-down, G-up
- "G+H" bound to a program will emit: G-down, G-up ... <programEventsAsGeneratedMergedWithActualKeyMatrixStateButWithGandHkeysHidden>
- "Alt-F" bound to Ctrl-F exclusive macro: Alt-down, Alt-up, Ctrl-down, F-down, F-up, Ctrl-up, and if Alt is still pressed at this time then Alt-down, Alt-up
- "MacroKey-F" bound to Ctrl-F mergable macro: Ctrl-down, F-down, F-up, Ctrl-up but this is all merged with the actual keyMatrix state, e.g. if Shift would be pressed too then Shift-MacroKey-F would result in Shift-down, Ctrl-down, F-down, F-up, Ctrl-up, Shift-up (when the Shift is really released by user)
If one does not want some "wrong" key presses emitted to OS just because they are launcher keys for a macro then he should use MacroShift or LayerShift modifiers. Standard shifters (Shift,Alt,Ctrl,Win) can be often used too since they typically do not do anything wrong in the OS when pressed and released. Well, it depends. Win key press/release in MS Windows did open start menu in the past ... and possibly it still does. So it may be a good idea to avoid Win modifier in a macro launcher on MS Windows.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
But it should swallow G completely - it's a part of macro trigger, after all. What's the point of having a macro which outputs garbage before the actual macro sequence?vvp wrote: ↑"G+H" bound to an exclusive macro will emit: G-down, G-up, ... <macroSequenceAsDefined-AllKeyMatrixStateHidden>, and if G is still pressed at this time then G-down, G-up
But then what if you have g+h and g+i macros and hold "g", type "h" then type "i"?
I can go on and on with edge cases - but what I need is a coherent model which would explain the world of macros.
As for "matrix state hidden".. I want to avoid all that "matrix state" as much as humanly possible. Because switching will basically cause lots of modifier keypresses and this doesn't play well with Windows at least - heard of StickyKeys? And if there's non-mod key still down when macro starts playing - here you go, double keypresses reported.
MacroKey is just another layer switch key, nothing special there. I would like to avoid special macro scancodes altogether btw, by using normal scancodes you don't need (don't tell me you NEED "Keypad {" ). Primary reason is I _really_ want to keep layout "one byte per scancode" - and I want multimedia and system control keys to be there too.
..but even without a coherent model, those were useful examples. A good non-self-contradicting model describing the state machine around macros would be super though
While trying to invent that, keep in mind that keyboard doesn't talk in "key-down, key-up" protocol - it sends "all keys pressed at this particular moment", and what happens when 2 new keys appear in the report at the same time is UNDEFINED BEHAVIOR. Model's outputs must be compatible with this restriction.
For example, because of this right now I only send ONE change per report, and keypresses appear N milliseconds away to give OS time to process them separately and in sequence. So if I detect "gf" 200 microseconds apart (and I can) - they will be reported 10(configurable) milliseconds apart, to reduce chance of OS interpreting it as "fg".
- vvp
- Main keyboard: Katy/K84CS
- Main mouse: symetric 5-buttons + wheel
- Favorite switch: Cherry MX
- DT Pro Member: -
I'm not trying to persuade you to implement your firmware the way my is. I'm only telling you how I solved it.
Of course, it is easy to modify firmware so that the double key is not emitted even when it is part of a key of some exclusive macro trigger. The firmware would hide not only the main trigger key but all of them (as done when launching programs). But that would be worse since if you would have e.g. macro at Alt-G and you would want to start this Alt-G macro followed by (non-macro sequence) Alt-A then you would need to release and press again Alt between G and A. That would suck even more.
Users just should not add more than 1 non-modifier key into macro trigger.
As for as trying to invent a clean model: it is a waste of time. Clean model is impossible. So each firmware must select its own set of compromises.
The point is so that you do not postpone emitting G-down event. Because that would be even worse in my opinion. That is the reason to use modifier keys or layerShifts in the trigger where the garbage does not matter much (shift keys) or there is no garbage (layerShifts).DMA wrote: ↑But it should swallow G completely - it's a part of macro trigger, after all. What's the point of having a macro which outputs garbage before the actual macro sequence?vvp wrote: ↑"G+H" bound to an exclusive macro will emit: G-down, G-up, ... <macroSequenceAsDefined-AllKeyMatrixStateHidden>, and if G is still pressed at this time then G-down, G-up
My firmware does this: If "g" is still pressed while "i" is pressed then you get the result of g+h macro followed by g+i macro.DMA wrote: ↑ But then what if you have g+h and g+i macros and hold "g", type "h" then type "i"?
Clean model is impossible without postponing key press events which I think is worse ... especially if the keyboard is sometimes used for playing games or with a separate mouse. If you want the keyboard only for typing and do not care about synchronization with other devices (and therefore do not care about postponing key press events) then there is no problem creating a clean model. That will not output any garbage and will not confuse windows sticky keys (which can be deactivated anyway).DMA wrote: ↑ I can go on and on with edge cases - but what I need is a coherent model which would explain the world of macros.
Yes, if it was part of exclusive macro trigger. No, if it part of merging macro trigger. If it is not part of macro trigger then the macro is not triggered.DMA wrote: ↑ And if there's non-mod key still down when macro starts playing - here you go, double keypresses reported.
Of course, it is easy to modify firmware so that the double key is not emitted even when it is part of a key of some exclusive macro trigger. The firmware would hide not only the main trigger key but all of them (as done when launching programs). But that would be worse since if you would have e.g. macro at Alt-G and you would want to start this Alt-G macro followed by (non-macro sequence) Alt-A then you would need to release and press again Alt between G and A. That would suck even more.
It is impossible without postponing key press events. Which I think is even worse option. This is also the reason why I do not like things like e.g. Space-Fn (it fiddles with space press timing).DMA wrote: ↑ A good non-self-contradicting model describing the state machine around macros would be super though
Users just should not add more than 1 non-modifier key into macro trigger.
Of course, but it is much easier to describe (on this message board) the sequence of press/release events than enumerate whole keyboard state at every key matrix state change. Believe me, you would not want to decipher USB reports more or less as they are sentDMA wrote: ↑ While trying to invent that, keep in mind that keyboard doesn't talk in "key-down, key-up" protocol - it sends "all keys pressed at this particular moment",
As for as trying to invent a clean model: it is a waste of time. Clean model is impossible. So each firmware must select its own set of compromises.
Interesting. I did not know that. Do you have any reference? I do not see why OS should have any problem with this. If there are changes of state of two keys in the same keyboard report then the OS can just order it whatever way it likes when notifying programs. That does not sound like a problem to me.DMA wrote: ↑ and what happens when 2 new keys appear in the report at the same time is UNDEFINED BEHAVIOR.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Got it. It looked a bit like the former to mevvp wrote: ↑I'm not trying to persuade you to implement your firmware the way my is. I'm only telling you how I solved it.
Don't like the idea of non-merging macros still. "easy to modify firmware" sounds like programming, really - and users are notoriously bad at that thing.
Device Class Definition for Human Interface Devices (HID) Version 1.11, Appendix C(page 62) says:vvp wrote: ↑Interesting. I did not know that. Do you have any reference?
It also says "The keyboard must report a phantom state indexing Usage(ErrorRollOver) in all array fields whenever the number of keys pressed exceeds the Report Count" and other things no one in community firmwares cares forThe order of keycodes in array fields has no significance. Order determination is done by the host software comparing the contents of the previous report to the current report. If two or more keys are reported in one report, their order is indeterminate. Keyboards may buffer events that would have otherwise resulted in multiple event in a single report.
Indeed, it is not a problem for OS. Only for user.vvp wrote: ↑I do not see why OS should have any problem with this.
People come to expect their keypresses to appear on the screen in an orderly fashion. So this would be a problem for them.vvp wrote: ↑If there are changes of state of two keys in the same keyboard report then the OS can just order it whatever way it likes when notifying programs. That does not sound like a problem to me.
- vvp
- Main keyboard: Katy/K84CS
- Main mouse: symetric 5-buttons + wheel
- Favorite switch: Cherry MX
- DT Pro Member: -
Ach rigth, it is programming indeed. I meant that it is one/two lines of change for me in firmware. The change I do not want to do anyway since I think it would be worse after it.DMA wrote: ↑ Don't like the idea of non-merging macros still. "easy to modify firmware" sounds like programming, really - and users are notoriously bad at that thing.
As for as having two kinds of macros (exclusive and merging) then I like it. You may want to use a macro trigger like layerShift-A to emit e.g. Shift-F1. This is a kind of macro which should be merging with the keyboard state so that if you get Ctrl-Shift-F1 when you pres Ctrl-layerShift-A. On the other side, if you have a macro which inserts e.g. your signature at the end of a text message then you definitely want it replayed just the way it was defined (i.e. it should not merge with the actual key matrix state). Non-merging macros are useful when you can (re)define them on-the-fly (like on Kinesis Advantage) and use them to insert longer character input on a single trigger.
OK, thanks for clarification. I already thought that maybe I need to fix something. It should not be an issue for user in my point of view. If user changes state of two keys within one USB polling interval then he/she cannot expect that applications are notified about the change in some specific order. The user will not be able to press/release the keys in the given order with any kind of reliability anyway when we are down to about 1 ms time interval.
If you meant it only in the scope of macros then they must be re-played one event at a time to preserve ordering, of course.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Experimented a bit with PCB design.
This is F122 under-PCB mylar sheet with craft store 1/4"-wide copper tape pasted to it. Row lines are run all the way across it, flipper legs standing right on them (I aimed for "about 2/3rds of the strip is under the flipper").
Leftmost and righmost columns just run across the rows, forming 1/16 sq. in. overlay between row and column.
Middle columns tape is cut to 1cm pieces and connected with thin wires, forming sort of a dashed line, to minimize overlay. Right column has a standard gap between pads (0.015"?), left has zero gap (red on the photo marks the pad border).
Right half has additional 1/4" square pieces of copper pasted as far away from the row line as possible, but in a way that flippers still completely cover them.
It is sandwiched into bolt-modded unicomp (layers are "barrels - "sense card" - unicomp's original rubber membrane - metal plate"), and controller connected to the end of the strip, like this: It's not much worse than PCB proper.
Readouts at rest are 5-8(looks like the gap is the main factor affecting the levels) on dashed columns, 28-30 on solid ones.
Keypress gives +10 (+15 if there's additional copper piece under the flipper).
Readouts are stable and variation is SURPRISINGLY LOW.
So it looks like PCB can be replaced with a mylar sheet with conductive pads printed on it, akin to the one used in model M. Can't find how much those cost though. I think they must be cheaper than PCB.
This is F122 under-PCB mylar sheet with craft store 1/4"-wide copper tape pasted to it. Row lines are run all the way across it, flipper legs standing right on them (I aimed for "about 2/3rds of the strip is under the flipper").
Leftmost and righmost columns just run across the rows, forming 1/16 sq. in. overlay between row and column.
Middle columns tape is cut to 1cm pieces and connected with thin wires, forming sort of a dashed line, to minimize overlay. Right column has a standard gap between pads (0.015"?), left has zero gap (red on the photo marks the pad border).
Right half has additional 1/4" square pieces of copper pasted as far away from the row line as possible, but in a way that flippers still completely cover them.
It is sandwiched into bolt-modded unicomp (layers are "barrels - "sense card" - unicomp's original rubber membrane - metal plate"), and controller connected to the end of the strip, like this: It's not much worse than PCB proper.
Readouts at rest are 5-8(looks like the gap is the main factor affecting the levels) on dashed columns, 28-30 on solid ones.
Keypress gives +10 (+15 if there's additional copper piece under the flipper).
Readouts are stable and variation is SURPRISINGLY LOW.
So it looks like PCB can be replaced with a mylar sheet with conductive pads printed on it, akin to the one used in model M. Can't find how much those cost though. I think they must be cheaper than PCB.
- Techno Trousers
- 100,000,000 actuations
- Location: California
- Main keyboard: IBM Model F-122
- Main mouse: Mionix Naos
- Favorite switch: Capacitive Buckling Spring (Model F)
- DT Pro Member: 0159
Wow, that's very interesting. A bonus with using a capacitive mylar sheet is you wouldn't have to heat bend it the way you might with a PCB. How does that sound in comparison? I'd think it would be a little more muted when the flipper whacks the mylar.
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
Another bonus is that it will fit FFC connectors because it's a Flat Flexible Cable, not a PCBTechno Trousers wrote: ↑Wow, that's very interesting. A bonus with using a capacitive mylar sheet is you wouldn't have to heat bend it the way you might with a PCB. How does that sound in comparison? I'd think it would be a little more muted when the flipper whacks the mylar.
It seems tad quieter than F122. May be because I haven't tightened the bolts, or because of the rubber underneath.
https://www.instagram.com/p/BUQAkq4BgQ7/- those are 12mm M2s, because I don't have 8mm ones.
It still has that F snappiness though.
I think there must be 3 mylar layers, actually. Protective top layer, then rows and then columns (assuming traces are printed on top. If they're on the bottom - protective layer needs to be below. I've heard those conductive inks are not durable and need to be protected from scratches.) Will probably still be cheaper than FR4.
-
- Location: Beamspringville
- Main keyboard: 4704
- DT Pro Member: 0186
I suspected that and expected it to work better because the distance between capacitance plates is much smaller providing a wider swing. I actually ran the theoretical math on another thread somewhere here (or on GH).DMA wrote: ↑ So it looks like PCB can be replaced with a mylar sheet with conductive pads printed on it, akin to the one used in model M. Can't find how much those cost though. I think they must be cheaper than PCB.
I kept working on using my vinyl-cutter to test but had issues with getting full layouts off in one piece. Had I realized it would work so 'rough and ready' I wouldn't have tried so hard.
Awesome work DMA!
Time to see if we can find another supplier.
(and damnit, time to buy another 2-3 PSoC boards)
- wcass
- Location: Columbus, OH, USA
- Main keyboard: ibm model m
- Main mouse: kensington expert mouse
- Favorite switch: buckeling spring
- DT Pro Member: 0185
I've done some work with custom membranes. I used InkjetFlex in August 2013. The print quality was awesome (copper on PET substrate) and good 4 mil thickness - close enough to Model M thickness (5 mil bottom, 3 mil top), but they stopped doing "prototype" service in early 2015. Cost was about $50 for two pieces about the size of 60% keyboard. It looks like they got bought out by CPI. Probably worth contacting them.
https://www.uk-cpi.com/inkjet-flex/
The next time I needed a custom membrane (mid 2015), I spent a few months checking 40 or 50 vendors who do silver bearing silk-screen (think Model M membranes). Most were in the neighborhood of $500 - $1000 for 10 pieces - again 60% keyboard size. I finally went with a Chinese manufacturer that said they could do it to my spec for $120. The result was ... 10 mil thick (not 5 mil) and the cuts were horrible - looked like they were done with a blow torch. I would not recommend.
So, ... at low volume, FR4 is better quality and a lot cheaper.
https://www.uk-cpi.com/inkjet-flex/
The next time I needed a custom membrane (mid 2015), I spent a few months checking 40 or 50 vendors who do silver bearing silk-screen (think Model M membranes). Most were in the neighborhood of $500 - $1000 for 10 pieces - again 60% keyboard size. I finally went with a Chinese manufacturer that said they could do it to my spec for $120. The result was ... 10 mil thick (not 5 mil) and the cuts were horrible - looked like they were done with a blow torch. I would not recommend.
So, ... at low volume, FR4 is better quality and a lot cheaper.