Tuesday, September 21, 2021

Building Arduino code as new controller for Documation card readers

CODING AND DESK CHECKING THE ARDUINO SKETCH

I chose to spend the day writing the code for the new interface controller for the card reader. It is compatible with the protocol developed by Brian Knittel but a totally different implementation. It will allow me to make use of two additional interface signals - Motion Check (MOCK) and BUSY - that weren't connected due to limitations of the IO Interface in his design.

The interface has 18 inputs and one output, plus a button and an LED to select and display the End of File (EOF) status. The Documation uses TTL signal levels and presents a 6 us pulse as an index marker (IM) at each of the eighty card columns, after which the interface will guarantee good data to sample for about 345 us. As long as the interface circuit can retrieve the data in that interval and transmit the twelve row bits once every 450 us, it can keep up with the 1000 card per minute reader. 

Using a serial USB link at 115,200 baud and transmitting two bytes with 8-N-1 serial protocol per column, I should be able to send it in 17.3 us. The ATMEL Mega2560 processor is clocked at 16MHz and can easily handle the instructions required drive the reader.

I chose the Mega2560 because it is TTL level compatible and has more than the 21 digital IO pins I need for this project - 18 inputs, one output, a button and an LED - plus it is easily procured and quite inexpensive. I know some techniques to ensure that it responds adequately to the timing requirements, having used this board for other projects of similar complexity in the past.

The ATMEL chip will watch certain I/O pins and trigger interrupts for events occuring on that line. I can hook the IM signal to one of these pins and have it trigger on the rising edge of the pulse. In the interrupt handler routine, I will directly access the ports of the chip to retrieve eight at a time quite rapidly.

I selected pins on the Arduino that are grouped together on eight bit ports that can all be read simultaneously. Using two such groups, in just a few hardware instructions I can extract all 12 row data values and four reader status signals. The routine then saves these in a variable and returns, setting a flag that it has processed an IM. 

The main loop checks for requests from the serial port after it deals with any IM that was processed. If an IM was handled, the loop will transmit the card data as two binary characters and bump the column counter. When the counter has handled the last data column, it sends one ASCII character which is the status byte defined by Brian's protocol.

If a request comes in, it is only for a very limited number of functions and consists of a single character. S requests the status byte be returned. P requests that the reader pick a card, producing the 80 columns of data triggered by the IM pulses and ends with a status byte. C, E and R are various reset functions to cancel picks, turn off the EOF status or reset the controller. Anything else is invalid and receives a '?' back. 

This code is a bit obscure compared to the usual Arduino sketch that uses digitalRead and similar macro commands to do I/O but is much faster. I can do some limited testing before I wire it up to the reader and give it a try. 


No comments:

Post a Comment