View previous topic :: View next topic |
Author |
Message |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
Is there a significantly faster way to do this ?? |
Posted: Fri Jul 13, 2012 10:47 am |
|
|
The function is the core of an 8x8 matrix key press detector.
it works and seems fast enough. But can it be done a whole lot better?
Code: |
// on entry Port D is all output, pulled high for gross keydown detection
// port B is pulled DOWN by 10K x8 and is the receive side of the key mtx
// at least one matrix closure was detected by the calling routine.
// OK[64] is a byte matrix that holds the character we want to output
// holdoff && repeats, etc handled externally
void decode88(void){ // ** decode and OUTPUT one or more keys pressed
byte work;
unsigned int8 i,j,r=1;
for (i=0; i<8; i++){ // now select one row at a time
output_d(r);
delay_us(10); // for TTelmah - ;-))
work=input_b();
if (0!=work){ // found closure on this row
for (j=0; j<8; j++){ // now which column ?
if( bit_test(work,j)){ // closure on this column
putc(ok[((8*i)+j)];
} // if bitsy
} // j loop
} // end WORK
r =r*2; // shift row bit
} //for i
output_d(255); // raise all lines for next detect
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jul 13, 2012 2:54 pm |
|
|
Two things stand out to be relative slow:
1) The 10us delay, why is it there? Do some calculations and most likely you can use a shorter delay, possibly after decreasing the 10k resistors.
2) The putc is dangerous. The UART can only buffer 1 character and will stall for a relative long time when data is already waiting to be sent. Much better to use the well known interrupt driven transmit buffer from the ex_stisr example. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9216 Location: Greensville,Ontario
|
|
Posted: Fri Jul 13, 2012 2:58 pm |
|
|
Without seeing the listing....
r =r*2; // shift row bit
might be better done using the 'shift' function ??
also.... be sure to figure out the 'debounce' requirement... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19480
|
|
Posted: Sat Jul 14, 2012 4:13 am |
|
|
The compiler will optimise a fixed *2, to a shift, so makes no difference.
On the delay, 10uSec is 'long', even with 10K resistors. The value needed is going to depend on the total capacitance of the lines, and the resistances of the switches themselves, but I'd have guess a uSec or two would have been enough.
The putc, is worse than 'dangerous'. As it stands, assuming 9600bps, you could be stuck inside the routine for over 60mSec, if all the switches were made!.... Agree wholeheartedly - buffer.
I have to say 'why' have the block testing outside the routine?. To my mind, tidier, to have this routine start by outputting 255, and immediately test and return if input_b==0.
The routine also makes no attempt to ignore keys that are 'held', so will keep being called, and keep delaying for putc when this happens....
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sat Jul 14, 2012 9:23 am |
|
|
Thanks for excellent tips:
1- Baud is 115200 using FTDI to USB interface, inter-key dead band is 100msec typical - 'holdoff' timing is external too. I only showed the core decoder - which is called with external timing control so as not to repeat when not valid initially or timed out - I also omitted the assignment of output char to BYTE curkey as not being relevant to the routine's basic efficiency.
2- The routine is never called in the first place unless a read of port b comes up with !=0 using portd= 255 - thats why the routine must end with portd =255
3- I considered bugging out of the loops with a return as soon as any code is detected by row scan of port d but left it as it is to detect multiple keys being pressed - THAT is the main area of uncertainty I was hoping to optimize, but saw no clear way to do it.
4- 10us was safely longer than needed as I could see bounce port b pins
with 18" cable to pic and is 10x longer than I need - shorter than 1 us
delay gave the odd bad code output.
5- Being a printed carbon matrix with 500 ohms or more closed - 10k was judged a safe enough load to allow for deterioration after many many presses of lifetime activity. |
|
|
|