Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Custom Modulation Scheme


I'm trying to emulate a custom modulation scheme, and I was wondering if anyone has any suggestions on the best way to do this. The scheme is a pulse modulation scheme where ones and zeros are indicated by the amount of time between pulses (short for 0, long for 1), and bytes are separated by a long pulse. You can see a sample scope reading here:

I tried implementing it by bit banging the coil in Python, for example:

if (b&(1<<i)):

result, data= rfidler.command("COIL LOW")
result, data= rfidler.command("COIL HIGH")
result, data= rfidler.command("COIL LOW")
result, data= rfidler.command("COIL HIGH")
i = i - 1
result, data= rfidler.command("COIL LOW");

But it doesn't work, I'm guessing because sending the command over serial has a timing delay I'm not taking into account, and Python timing isn't great on the sub-millisecond scale.

Another thought I had was using ASK emulation-- while it doesn't support this scheme, I could write a script to calculate the bits that would lead to the right output on the coil for a certain frequency.

And of course as a last resort I could always modify the firmware.

Do any of these  seem like they would be the 'best' way? Is there an easier approach I'm missing here?


  • Yes, in the short term, I would use ASK with a pseudo bit pattern as that should give you extremely accurate timings.

    Modding the firmware to support this scheme shouldn't be that hard - all the modulation is done by a single ISR and a few startup routines, and the same for demodulation - see ask.c for example...
  • I tried using the psuedo-bit pattern, and it didn't work. I eventually attached a signal analyzer to the coil, and found it wasn't transmitting at all. My guess as to what was happening is that the RFIDler requires the device reading the emulated device to transmit excitation/engergizing waves before it transmits ASK. Does that make sense? Is there a way I can make the RFIDler transmit the emulated waveform without waiting for excitation? 

    The device I am trying to emulate uses RFID as an NFC-style protocol with multiple transmissions, and no excitation pulses (both devices are active)

    In the meantime, I've updated the firmware with a command that bitbangs using CLOCKH and STOP to emulate the device. 

  • When RFIDler is emulating a tag there is no "transmission". It is just grounding it's coil (or not). If you want to transmit in the way you're describing, what you're actually doing is emulating an active reader, and for that you want the "RWD" command (stands for "Read Write Device").

    First, set the timings with:

    PWM <FC> <SLEEP> <WAKE> <PW0> <PW1> <GAP> <TXRX> <RXTX>


      FC = Field Clock (800 for 125 KHz)
      SLEEP = Number of FCs to shut down coil before start
      WAKE = Number of FCs to energise coil before sending first bit
      PW0 = Number of FCs in a '0' pulse
      PW1 = Number of FCs in a '1' pulse
      GAP = Number of FCs to shut down coil between bits
      TXRX = Number of FCs to wait between sending a bit pattern and listening for response (not used for one-off commands)
      RXTX = Number of FCs to wait between receiving tag data and sending next command (not used for one-off commands)

    Then you can simply send the ID bits with:


    See "EXAMPLES" for an example of sending a HITAG2 start command.

  • Thanks, that's really helpful! 

    Unfortunately, it doesn't look like the command will quite work with my device though. It's missing a few things necessary for the protocol (from what I can tell):

    - GAP is the same for a one and a zero, meanwhile in the protocol I'm trying to emulate, it's different (in fact, PW0 and PW1 are the same, and it's the amount of time the signal is low that makes the difference between a 1 and 0)
    - There's a separator pattern that's a different pulse width than ones and zeros in the protocol between bytes
    - It would be nice if there was an option to do multiple transmissions without reading

    I'm going to see if I can update the firmware with a 'fine-tuned' version of PWM that allows these options

  • I would suggest you simply change low level GAP to GAP0 and GAP1, so it will be easy to maintain compatibility with existing standards such as HITAG2 by setting them to be the same, but for your application they can be different. Should mean very minor modifications to the code.

    The repeat could be implemented at a higher level in the RWD command itself - e.g. :


Sign In or Register to comment.