2

Does anybody have any clue how to control the bi-color LED of ACR122U via the method Reader.control() on Android? (library acssmc-1.1.3).

I am reading the API and have no idea what the command description means:

Example:

byte[] command = {(byte) 0xFF, (byte) 0x00, (byte) 0x40, (byte) 0b01110111, (byte) 0x04, (byte) 20, (byte) 30, (byte) 3, (byte) 2};

These things I do not understand:

  • Byte 3 (P2): I cannot figure out how to set that up.
  • Byte 5 (T1): First cycle state duration that is somehow controlled from byte 3?
  • Byte 6 (T2): Second cycle state duration that is somehow controlled from byte 3?
  • Byte 7 (number of repetitions): Number of total 1st and 2nd cycle state repetitions?

Some explained examples would be awesome.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
gnivirht
  • 315
  • 2
  • 9

1 Answers1

10

The command to change the LED state is

+------+------+------+------+------+------+------+------+------+
| CLA  | INS  | P1   | P2   | Lc   | DATA                      |
+------+------+------+------+------+------+------+------+------+
| 0xFF | 0x00 | 0x40 | SC   | 0x04 | T1   | T2   | #R   | 0x00 |
+------+------+------+------+------+------+------+------+------+

where SC defines the state of the LEDs (continuously on/off, blinking), T1/T2 define the blinking wave form, and #R defines the number of repetitions of the blinking wave form.

So the main parameter to define how the LEDs should blink and how they should look after blinking finished is SC. This is a field of 8 bits:

  • Bit 0: This flag defines the state of the red LED after blinking finished (see also bit 2).
  • Bit 1: This flag defines the state of the green LED after blinking finished (see also bit 3).
  • Bit 2: Only if this flag is set (1), the state of the red LED will be set to the value of bit 0 after blinking finished. If this flag is cleared (0), the red LED will return to the state that it had before you issued LED control command.
  • Bit 3: Only if this flag is set (1), the state of the green LED will be set to the value of bit 0 after blinking finished. If this flag is cleared (0), the green LED will return to the state that it had before you issued LED control command.
  • Bit 4: This flag defines the state that the red LED should be set to at the beginning of executing the LED control command.
  • Bit 5: This flag defines the state that the green LED should be set to at the beginning of executing the LED control command.
  • Bit 6: This flag defines if the red LED should be toggled with the blinking wave form.
  • Bit 7: This flag defines if the green LED should be toggled with the blinking wave form.

So lets assume that you set bits 4 and 6 of SC (and clear the rest), i.e. SC = 0x50. Further, you set T1 = 5 (0x05), T2 = 10 (0x0A), and #R = 2 (0x02). Thus, you have the following command:

+------+------+------+------+------+------+------+------+------+
| 0xFF | 0x00 | 0x40 | 0x50 | 0x04 | 0x05 | 0x0A | 0x02 | 0x00 |
+------+------+------+------+------+------+------+------+------+

Then the green LED will be off and the red LED will blink two times with the following wave form:

RED ON   ----------\                    /----------\
                   |                    |          |                    
RED OFF            \--------------------/          \-------------------- 

         \________/ \__________________/ \________/ \__________________/
         T1 = 500ms     T2 = 1000ms      T1 = 500ms     T2 = 1000ms

         \_____________________________/ \_____________________________/
                  Repetition 1                    Repetition 2

Now, lets assume that you also want to blink the green LED, but with its initial state set to off (so that blinking switches between red and green instead of red and no light). Therefore, you also set bit 7 of SC, i.e. SC = 0xD0. Thus, you have the following command:

+------+------+------+------+------+------+------+------+------+
| 0xFF | 0x00 | 0x40 | 0xD0 | 0x04 | 0x05 | 0x0A | 0x02 | 0x00 |
+------+------+------+------+------+------+------+------+------+

Then the red LED and the green LED will alternately blink two times with the following wave form:

RED ON     ----------\                    /----------\
                     |                    |          |                    
RED OFF              \--------------------/          \--------------------

GREEN ON             /--------------------\          /--------------------
                     |                    |          |                    
GREEN OFF  ----------/                    \----------/

           \________/ \__________________/ \________/ \__________________/
           T1 = 500ms     T2 = 1000ms      T1 = 500ms     T2 = 1000ms

           \_____________________________/ \_____________________________/
                    Repetition 1                    Repetition 2

Now, lets assume that after blinking finished, you want the red LED to be continuously on and the green LED to be continuously off. You therefore need to set bits 2 and 3 in order to be able to define a final state of the two LEDs. (If you do not set those bits, then the values of bits 0 and 1 will simply be ignored.) You then want to define a final state of red on (bit 0 = 1) and gree off (bit 1 = 0). Consequently, you get SC = 0xDD. Thus, you have the following command:

+------+------+------+------+------+------+------+------+------+
| 0xFF | 0x00 | 0x40 | 0xDD | 0x04 | 0x05 | 0x0A | 0x02 | 0x00 |
+------+------+------+------+------+------+------+------+------+

Then the red LED and the green LED will alternately blink two times, the red LED will be turned on after blinking, and the green LED will be turned off. You get the following wave form:

RED ON     ----------\                    /----------\                    /--------------...
                     |                    |          |                    |
RED OFF              \--------------------/          \--------------------/

GREEN ON             /--------------------\          /--------------------\
                     |                    |          |                    |
GREEN OFF  ----------/                    \----------/                    \--------------...

           \________/ \__________________/ \________/ \__________________/
           T1 = 500ms     T2 = 1000ms      T1 = 500ms     T2 = 1000ms

           \_____________________________/ \_____________________________/ \_____________...
                    Repetition 1                    Repetition 2             Final state

Finally, you want to reduce the number of repetitions to 1 (#R = 0x01) and you want to invert the high and low phases of the blinking wave form (T1 = 0x0A and T2 = 0x05). Thus, you have the following command:

+------+------+------+------+------+------+------+------+------+
| 0xFF | 0x00 | 0x40 | 0xDD | 0x04 | 0x0A | 0x05 | 0x01 | 0x00 |
+------+------+------+------+------+------+------+------+------+

You get the following wave form:

RED ON     --------------------\          /--------------...
                               |          |
RED OFF                        \----------/

GREEN ON                       /----------\
                               |          |
GREEN OFF  --------------------/          \--------------...

           \__________________/ \________/
               T1 = 1000ms      T2 = 500ms

           \_____________________________/ \_____________...
                    Repetition 1             Final state
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Did you actually test this? I am unable to get the LED state to remain after the command has completed. It blinks fine but unfortunately it goes back to the default state (red) after the command is finished. I am using your example: `[0xFF, 0, 0x40, 0xDD, 0x04, 0x05, 0x0a, 0x02, 0x00]`. – André Borie Apr 04 '17 at 12:45
  • @AndréBorie Yes, it works on the two ACR122U readers that I have here. – Michael Roland Apr 04 '17 at 14:33
  • @MichaelRoland would you mind sharing the exact code you used? I would like to try this. I noticed the LED state is reset every time the reader detects a card - the only way to leave the LED state for me is to set them while the card is in the field and then stop polling the reader (by stopping `pcscd`). – André Borie Apr 04 '17 at 15:23
  • @AndréBorie I don't have any code for this, I used an APDU scripting tool to send those APDUs to the reader. Obviously, if you have a version of the reader that automatically detects cards (which is a newer one that I have), then the reader will reset LED state and you will probably have to set them again upon detection. I'm not sure why you would want to stop pcscd for this though. – Michael Roland Apr 04 '17 at 17:49
  • @MichaelRoland Pcscd seems to be polling the cards for me even if no programs are actually using the card reader, which causes the LED to reset everytime a card is detected. By stopping it at the very least I can get the LED to stick to whatever state it was before the card was removed. Awful solution but better than nothing in the meantime. Thanks anyway. – André Borie Apr 04 '17 at 21:55
  • @AndréBorie Any update on how to make the led stay green after sending the command, I am seeing the same behavior it reverts to red after the command is complete, I cannot make the led stay green after the command completes, it looks like pscd is overwriting the state. – Aravind Oct 30 '22 at 02:42
  • @Aravind apologies - I don't even remember whether I ever solved it. If you got your reader from a specialized distributor maybe worth sending them an email and see if they can pass it on to ACS - maybe they have the answer? Best of luck in any case. – André Borie Oct 31 '22 at 10:19