TK. Posted February 12, 2012 Report Posted February 12, 2012 Finally we've a proper solution for scanning a velocity sensitive keyboard at fast speed (300 uS) with low CPU load (so that other tasks can be processed in parallel). -> http://svnmios.midibox.org/listing.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Ftutorials%2F029_keyboard_velocity%2F I tested it on a defective Korg microKONTROL - the original firmware scanned the keyboard only at 500 uS, which means that the app has a higher accuracy than the commercial solution. :) Details are described in the README.txt Best Regards, Thorsten. Quote
nlate Posted February 13, 2012 Report Posted February 13, 2012 (edited) Hello Thorsten Details are described in the README.txt " ... MIOS32_SRIO_ScanStart is now called immediately (again) when a scan has finished, accordingly only the transfer rate limits the scan speed. It has been set to MIOS32_SPI_PRESCALER_64 (0.64 uS on a 120 MHz LPC1769). The resulting matrix scan speed is ca. 300 uS for 16 rows and 8 columns (= 512 contacts) .... " I don´t understand your calculation. As far as I can follow there are 2 ser. DOUT register for the rows an 1 ser. DIN register for the columns which lead to 16 x 8 = 128 contacts or 64 early & final contacts pairs. This means for me 64 keys with velocity sensing. Supposing (16 bits [for DOUT] + 8 bits [for DIN])/row * 0.64 uS/bit * 16 rows = 246 uS plus some spare processing time leads to the aforementioned 300 uS scan time but for 128 contacts. Where is my error in reasoning? Regards Jo Edited February 13, 2012 by nlate Quote
TK. Posted February 13, 2012 Author Report Posted February 13, 2012 Finally somebody who reads the README! :) I fixed the wrong value, 128 contacts are scanned of course! Note that only 16 bits have to be shifted per row, since DINs are read concurrently to DOUT shift-out. The additional overhead is caused by interrupt latency and (unoptimized) value transfers + pin change detection into C arrays before the next 16bit scan is started. Best Regards, Thorsten. Quote
nlate Posted February 14, 2012 Report Posted February 14, 2012 Hi Thorsten, Thanks for correcting the Readme.txt Note that only 16 bits have to be shifted per row, since DINs are read concurrently to DOUT shift-out. Aah, I forgot, that's the nature of SPI, Regards, Jo Quote
nlate Posted February 16, 2012 Report Posted February 16, 2012 Hi Thorsten, I looked into the code at app.c of tutorial #29 and have some (may be silly) questions: Why don´t you use a debounce fct. ? Is this not necessary, because today´s keyboards (Fatar etc.) use bubble contacts.If I want to use 16bit (u16) array variables, to save valuable RAM space, does this cost more exec cycles on an ARM core? (I am an injured Intel x86 guy :pirate:)What about timestamp wraparound? (after 15 days running the tutorial) Thanks in advance for responding. Kindly Regards Jo Quote
TK. Posted February 16, 2012 Author Report Posted February 16, 2012 Hi, here my silly answers: Why don´t you use a debounce fct. ? Is this not necessary, because today´s keyboards (Fatar etc.) use bubble contacts. It wasn't necessary when I tested it with the Korg keyboard. If you notice a bouncing issue, please let me know and I will improve the example! It could be solved by adding a simple check: the note on event should only be sent once after the "early contact" has been activated, and note off should only be sent once after the "final contact" has been deactivated. (no debounce counter is required) [*]If I want to use 16bit (u16) array variables, to save valuable RAM space, does this cost more exec cycles on an ARM core? (I am an injured Intel x86 guy :pirate:) If I understand your question correctly, you propose to change the din_activated_timestamp array into a u16 array, right? This shouldn't hurt. [*]What about timestamp wraparound? Thats no issue in the way how I've implemented the delay measurement. As long as we are calculating with values in the same resolution range (int and u32 are both 32bit values), the wraparound will take place by construction; the delay will always be correct. Best Regards, Thorsten. Quote
nlate Posted February 16, 2012 Report Posted February 16, 2012 Thanks Thorsten for your immediate and detailed answers Best Regards, Jo Quote
TK. Posted February 19, 2012 Author Report Posted February 19, 2012 I improved the tutorial application based on your proposals: - timestamps are now stored in u16 resolution. I also added a hint, why delay needs to be "s16" type now. - added debouncing mechanism Best Regards, Thorsten. Quote
nlate Posted February 20, 2012 Report Posted February 20, 2012 (edited) Hi Thorsten I admire your passion in bringing ideas to well structured code! Imho APP_SRIO_ServicePrepare() and APP_SRIO_ServiceFinish() can be accellerated: Skip MIOS32_DOUT_SRSet() of final contact row 2, 4, 6, 8, 10 for the Korg KB if din_value of the related early contact row 1, 3, 5, 7, 9 is 0xff (no early contact pressed) I observed this behavior on a Fatar keyboard some time ago, see: one small side note to your Readme.txt and code comments, I´m a little confused about the meaning of your word depressed. Does it mean released/untouched? Kindly Regards, Jo Edited February 20, 2012 by nlate Quote
TK. Posted February 20, 2012 Author Report Posted February 20, 2012 Imho APP_SRIO_ServicePrepare() and APP_SRIO_ServiceFinish() can be accellerated: Skip MIOS32_DOUT_SRSet() of final contact row 2, 4, 6, 8, 10 for the Korg KB if din_value of the related early contact row 1, 3, 5, 7, 9 is 0xff (no early contact pressed) Nice idea! :) But it only makes sense if the selection pattern is used for a single matrix. Meanwhile I started with MIDIbox KB: http://svnmios.midibox.org/listing.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Fcontrollers%2Fmidibox_kb_v1%2F which can service multiple keyboards of multiple types - here such an optimization would lead to unnecessary complexity, especially once the remaining DOUTs should be used for driving a LED matrix as well. one small side note to your Readme.txt and code comments, I´m a little confused about the meaning of your word depressed. Does it mean released/untouched? Yes. Google gives me 30 million hits for "depress button", I hope that they don't need antidepressant drugs... ;-) Anyhow: http://www.thefreedictionary.com/depress Best Regards, Thorsten. Quote
nlate Posted February 21, 2012 Report Posted February 21, 2012 (edited) Hi Thorsten, Aggreed to all your points :) Just had a rough look at the new project you mentioned above. Looks very promissing. Looking forward for your coded ideas.:) Kindly Regards, Jo PS: If you are in the Bodensee region, let me know via pm. Appart from cristal-clear water, we also have several sorts of good beer!. :wink: Edited February 21, 2012 by nlate Quote
nlate Posted February 28, 2012 Report Posted February 28, 2012 Hi Thorsten Meanwhile I started with MIDIbox KB: http://svnmios.midib...idibox_kb_v1%2F which can service multiple keyboards of multiple types - here such an optimization would lead to unnecessary complexity, especially once the remaining DOUTs should be used for driving a LED matrix as well. I think I found a small bug in http://svnmios.midib...rc%2Fkeyboard.c in fct. void KEYBOARD_Periodic_1mS(void) { ::::::::::::::: ::::::::::::::: // check all 8 pins of the SR // should be: 16 ? int sr_pin; u8 mask = 0x01; // should be: u16 mask = 0x0001; for(sr_pin=0; sr_pin<16; ++sr_pin, mask <<= 1) if( changed & mask ) KEYBOARD_NotifyToggle(kb, row, sr_pin, (din_value[kb][row] & mask) ? 1 : 0); } } } Regards, Jo Quote
TK. Posted February 28, 2012 Author Report Posted February 28, 2012 You are wrong: these are two bugs! ;-) (fixed) Btw.: meanwhile I think that I should provide the scan optimization that you found for Fatar solution as an option - it will work as long as the selection pattern isn't used for other purposes, and if it isn't enabled by default, somebody can troubleshoot the matrix connections first before enabling this feature. Best Regards, Thorsten. Quote
nlate Posted January 3, 2015 Report Posted January 3, 2015 (edited) Dear Thorsten, dear MIDIBOXers First of all Happy New Year 2015! During regression tests of the midibox_kb_v1 project I found a nasty bug in SVN.MIOS32\trunk\modules\keyboard\keyboard.c at the KEYBOARD_NotifyToggle() fct.: // released key ? if( depressed ) { ..... [L578]: s16 delay = *ts_break_ptr - *ts_make_ptr; ..... and } else { // pressed key ? ..... [L631]: s16 delay = *ts_make_ptr - *ts_break_ptr; ..... } the (signed short) variable s16 delay leads to the following behaviour during delay calculations in case of overrun (s. 2nd & 3rd line during a debug session): [18721.553] Released: s16 delay= 17982 = u16 ts_break=58069 - u16 ts_make =40087 [18796.922] Pressed : s16 delay= 24956 = u16 ts_make =14748 - u16 ts_break=55328 [18817.231] Released: s16 delay=-20449 = u16 ts_break=40161 - u16 ts_make =60610 /!\ :sad: the 2nd line is still correct because the subtraction doesn´t exceed the positive range of the (signed short) s16 delay range. the 3rd line is mathematically correct, but not from the applicational view point. The local fct.: [L802]: static int KEYBOARD_GetVelocity(s16 delay, u16 delay_slowest, u16 delay_fastest) doesn´t handle negative delay values correctly because it handles all values below delay_fastest as max. velocity! So I changed the delay values in line 578, 631 & 802 from s16 to u16 with the result that the overrun case is now handled correctly: Released: u16 delay= 17982 = u16 ts_break=58069 - u16 ts_make =40087 Pressed : u16 delay= 24956 = u16 ts_make =14748 - u16 ts_break=55328 Released: u16 delay= 45087 = u16 ts_break=40161 - u16 ts_make =60610 :rolleyes: Thorsten, would you be so kind to check if my findings are correct, and make the proposed changes in modules/keyboard/keyboard.c and in apps/tutorials/029_keyboard_velocity/app.c if you confirm. Thanks and best regards, Jo Edited January 3, 2015 by nlate Quote
TK. Posted January 3, 2015 Author Report Posted January 3, 2015 Hi Jo. I wish you a happy new year as well! :) Thanks for reporting the finding! I agree and remember that I had similar experiences in the past, therefore fixed it immediately without additional testing at my side. Well, wouldn't it be nice if we would have some automated tests for such complex routines? ;-) Best Regards, Thorsten. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.