Well, thanks, guys, for sticking with me. I thought this was going to be a one or two evening project, but... now my wife says I'm obsessed. And in a sense I guess I am. If you lose interest I'll get by somehow. I ordered a Maple supposedly Arduino compatible that uses a different processor that runs a 5 times the speed. That should give me time to complete the analysis within the ISR.
I tried just stuffing the data into a buffer like you suggested in #8 and couldn't get that to work. I couldn't find a way to stop the buffer from overflowing when data comes in too rapidly. I have to analyze something before I tell it to stop.
Data bursts are at about 250,000 bytes per second. "Normal mode" is a couple of data bursts per second to display a clock and whatnot. These bursts range from 66 bytes each to occasionally 1062 bytes. (I might get a few dozen bytes inside these "normal" bursts that contain the "unique bytes" of the 10 numerals)
Other data: Of the 256 byte values only about 100 appear to ever get used as digits, letters or commands. (I looked at a string of 40,000 bytes as a representative sample. As long as I don't crash the system, all this normal mode data is junk. I'll don't think I'll ever get a false positive from it.)
A good finger swipe results in 4 bursts within two seconds, followed by 2 seconds of silence. They are 1024 bytes, 704 bytes, 1502 bytes (or 1216 bytes depending on how it clears the screen) and 66 bytes long. The first two bursts tell the user to remove their finger, the third provides information including the userID. The last 176 bytes of the 1502 byte burst are four zeroes and four digit drawings of the User ID.
(Each digit drawing is a 3 byte location command, 8 bytes of upper bitmap data, 3 more bytes location and 8 more bytes of lower bitmap data.)
The last 66 byte burst contains a colon and could be the cue to process the raw_digit string in the buffer. I poked around some more and just before the User ID string is the word "OK!" and the "K" contains a useful unique byte that can be used as a start collecting data signal.
Here is the code I'm using now:
All counters are volatile int and all data are volatile byte data types.
void setup (void)
{
Serial.begin (115200);
Serial.println (sketch); // Rick - always start by identifying what's actually in the Arduino
// have to send on master in, slave out
pinMode(MISO, OUTPUT);
// turn on SPI in slave mode
SPCR |= _BV(SPE);
// turn on interrupts
SPCR |= _BV(SPIE);
SPI.setDataMode(SPI_MODE2); // Rick - because of inverted clock in T&A - not used in testing between Arduinos
} // end of setup
// SPI interrupt routine
ISR (SPI_STC_vect)
{
if (SPDR==13) {start = 1;} // Rick - unique part of "OK" before User ID
if (SPDR == 198) {process = 1;} // Rick - unique inverse colon after UserID
if ((start==1) && (r < rmax)) {raw_digit[r++] = SPDR; } // Rick - only collect when within range
// Rick - I still need rmax in case I miss a 198 - may be overkill
} // end of interrupt service routine (ISR) SPI_STC_vect
void loop (void)
{
if ((r >= rmax) || (process == 1))// Rick - ISR got an inverse colon - rmax if I missed it
{
// Rick - caution: in a millisec ISR will start overwriting raw_digit[0]
rtemp = r;
r=0; // Rick - let interrupt go back to filling raw_digit
process = 0; start = 0; // Rick - wait for new start/stop from ISR
for (int i=0; i <= rtemp; i++){ work_digit = raw_digit*; } // Rick - get these moved in a hurry*
* for (m=0; m <=rtemp; m++) { getDigit(); } // Rick - m is global*
* // Rick - this for loop and getDigit returns with an array good_digit[ ] with g valid digits in it
get_user_id(); // Rick - convert all the good_digits to any valid out_digit (or userID)
_ g=0;_
} // end if process NOTE: get_user_id function now has a couple of seconds while ISR refills raw_digit*
} // end of loop
My test userIDs are 00000001, 00000002 and 00001945. A recent run of results was 00000002 00000200 00002520
00000100 00002010 00000220 00000210 00000100 00000001 00000001 00000021. I rarely get a successful output on a 00001945, I think because at least one of the zeroes gets lost. On the LCD you can see typically "OK! ID 00000002 1:1" When I put debug timers and counters in there I see even worse gaps, but then the main loop is doing Serial.print and timers, etc. which might be screwing it up. Again the data on the logic analyzer is good. Somehow the ISR is simply missing one or more of the zeros (and likely other bytes as well).
Until the Maple comes in, I'm going to study table lookups. Unless you have another suggestion. By the way, what is naked_ISR? Is that a function someone wrote?
Thanks.