Wiegand protocol RFID readers known to work with ESPHome?

Thank you!!! Common ground was my problem also

Can you shed some light about what your using and the details? I bought the keypad that’s used for thr pucture in the esphome docs and I can’t get it to work. Numbers are rarely detected. Key cards will show scanned very rarely. A lot of times nothing will show in the logs untill I power down the keypad the. Power it on and my logs start showing scans or key presses but after the power cycle it’s the same story. My grounds are all common and im using a level shifter as the data outs are just under 5v. Even if I scan something g twice the raw buts will be different so I can’t even use that approach because the sane tag doesn’t produce the sane bits each time. It’s super frustrating

Hi Justin

I’m certainly not an expert, but the below might help you with your issues. Maybe you’re having issues with the power supply? The first two power supplies i tried didn’t work for me (the keypad wouldn’t power on at all). The devices i am using are:

I have the KR602M hooked up to a 9V power cable from an old TP Link modem (i cut the Barrel plug off). I have the M5 Atom Lite connected to a separate 5V usb charger. The issue i was having initially was that i didn’t connect the ground for the KR602M keypad and the ground for the M5 Atom Lite together - so i wasn’t getting any data / key reads into the ESPHome log.

The next issue i faced was getting the data to be readable in home assistant. I was following the ESPHome guide (Wiegand keypad and tag reader — ESPHome and Key collector component — ESPHome) with the assumption that the keypad data would automatically pass through to home assistant but it didn’t. I needed to adjust the automation section to fire a home assistant event. My ESPHome config file is as follows:

esphome:
  name: keypad
  friendly_name: keypad

esp32:
  board: m5stack-atom
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "###"

ota:
  password: "###"

wifi:
  ssid: ###
  password: ###

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Keypad Fallback Hotspot"
    password: "###"

captive_portal:

wiegand:
  - id: mykeypad
    d0: 26
    d1: 32
    on_key:
      - lambda: ESP_LOGI("KEY", "received key %d", x);
    on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - homeassistant.event:
          event: esphome.wiegand_key_code
          data:
            key_code: !lambda 'return x;'
    on_raw:
      - lambda: ESP_LOGI("RAW", "received raw %d bits, value %llx", bits, value);

key_collector:
  - id: pincode_reader
    source_id: mykeypad
    min_length: 8
    max_length: 8
    end_keys: "#"
    end_key_required: true
    clear_keys: "C"
    allowed_keys: "0123456789"
    timeout: 5s
    on_progress:
      - logger.log:
          format: "input progress: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
    on_result:
      - logger.log:
          format: "input result: '%s', started by '%c', ended by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ]
      - homeassistant.event:
          event: esphome.wiegand_key_code
          data:
            key_code: !lambda 'return x;'
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]

I’m sorry - i’m not sure that this will be too helpful for you - i wonder whether you might have a defective power supply or keypad?

1 Like

I doubt either are defective as the keypad works just fine as a stand-alone keypad/rfid reader. I can program keycards and passwords and they toggle the internal relay, I can hear it since it’s a mechanical relay. The power supply i’ve been using is my work bench adjustable PSU i use for testing all my stuff and it get’s used daily since i put away the keypad project. In my manual you have to take steps to set it up for wiegand26 or wiegand34 output and the steps are different for each. I was able to get it into wiegand26 but couldn’t ever get the 34 to successfully work like it did with 26 by blinking green afterwards. I’m not sure if one or the other matters, 26 or 34? Did you have to mess with yours to set up wiegand26 output? The manual is hard to understand as it’s in Chinglish so lot’s of broken sentences or just confusing instructions. Is the one you use waterproof or resistant? This was meant to replace my Craftsman garage door keypad that quit working and it sits outside exposed.

This is the one I am working with. It appears to be the same one used as an example in esphome docs but you can never really be certain. Does yours output 5v on the data lines as well?
https://www.amazon.com/dp/B088M5ZZCV?psc=1&ref=ppx_yo2ov_dt_b_product_details

For anyone viewing this in the future, I got this to work and it was actually really simple after I figured out it was the crappy translation of the manual that was the problem! The process was 1. Short Reset jumper, press *, short D0 to ground and you should see the indicator led flashing red. The manual said to short D0 to ground then “click button” to complete the wiegand26 output mode. The instructions were backwards and “click button” is the English translation of “press *” in Chinese. Hopefully this helps someone else because mine was very close to finding itself embedded in my dry-wall after I lost my cool and threw it!

This is the keypad and it works excellent as a standalone keypad/rfid reader or with esphome and HA. I can’t speak to the longevity of it but, the whole pcb comes covered in a clear silicone waterproofing so I imagine it will be fine for a long time. https://www.amazon.com/Ultimate-Waterproof-Capacity-Stand-Alone-Installed/dp/B088M5ZZCV/ref=asc_df_B088M5ZZCV/?tag=hyprod-20&linkCode=df0&hvadid=475863965948&hvpos=&hvnetw=g&hvrand=5133014669273973660&hvpone=&hvptwo=&hvqmt=&hvdev=m&hvdvcmdl=&hvlocint=&hvlocphy=9016046&hvtargid=pla-1109018069213&psc=1

It probably didn’t need silicone/caulk but I had a tube open still and it’s just extra protection. I wish it was clear but it’s on my garage/mad scientist laboratory so F it.

3 Likes

Looking for some suggestions on what I might be doing wrong here using Wiegand in ESPHome. Had this setup in a much more complex way last year using a 26-bit card reader (no pin pad) attached to an Arduino, which passed the card reads over to a nodemcuv2 via serial. This worked but was too messy for me to really put into “production” performing tasks. Happened across this thread and pulled out a fresh nodemcuv2 and another card reader.

Using examples found in here, it works but have a minor problem. The same card cannot be read consecutively resulting in repeated actions, eg. open a door. If you read card A the door opens, you close the door. Read card A again, nothing happens. Read card B, then card A again, the door opens. I tried to blank out the sensor.rfid_tag 2 seconds after the automation runs, but upon rescanning the previously read card, the variable fails to update back to the read. Enabled the webportal for my esp, and it shows all of the card reads were successful.

Anyone have an idea what I’m missing here? Does the rfid_tag entity need to get wiped out after the read via the esp code? Looked into attempting that, but unfortunately I’m at a loss of how to accomplish this after multiple failed attempts at code.

esphome:
  name: accesscontrol
  platform: ESP8266
  board: nodemcuv2
wifi:
  ssid: !secret ssid1
  password: !secret ssid1pw
captive_portal:
web_server:
  port: 80
logger:
  level: DEBUG
api:
  password: !secret apipw
ota:
  password: !secret otapw
  
sensor:
  - platform: wifi_signal
    name: "Access Control WiFi"
    update_interval: 60s
  - platform: uptime
    name: "Access Control uptime" 

text_sensor:   
  - platform: template
    name: "RFID Tag"
    id: rfid_tag

wiegand:
  - id: reader
    d0: D1
    d1: D2
    on_tag:
      - lambda: ESP_LOGD("TEST", "received tag %s", x.c_str());
      - text_sensor.template.publish:
          id: rfid_tag
          state: !lambda 'return x;'   

i don’t see any automations that handle the tag being scanned or that open a door. I assume the automation is for some reason being handled by HA? I’m not sure why you didn’t keep it all local in your esphome config but, I imagine that’s where the problem is since this code isn’t doing anything except sending the tag being scanned to HA. How that scanned tag is used, you havn’t provided any of that information so no one can help you. Here is mine. It sends a service call to HA to open the door and there is also 2 sensors, one reports who’s tag was last scanned and the other, who’s password was last used and that’s all logged to HA so i can see the history.

For scanned tags.

on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - homeassistant.event:
          event: esphome.wiegand_key_code
          data:
            key_code: !lambda 'return x;'

     
      - lambda: |-
            if (x == "6491970"); {            
             id(OvrHead).toggle();
             id(last_user).publish_state("Mike Tag");
            } 

      - lambda: |-
            if (x == "6422842"); {            
             id(OvrHead).toggle();
             id(last_user).publish_state("Paula Tag");
            }       
            
      - lambda: |-
            if (x == "6753957"); {            
             id(OvrHead).toggle();
             id(last_user).publish_state("Justin Tag");
            }             

For Code entered.

 on_progress:
      - logger.log:
          format: "input progress: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]
    on_result:
      
      then:
        - lambda: |-
            if (x == "1050"); {            
             id(OvrHead).toggle();
             id(last_user).publish_state("Justin Code");
            } 

        - sensor.template.publish:
            id: keyCode
            state: !lambda "return parse_number<float>(x).value();"      
                
    on_timeout:
      - logger.log:
          format: "input timeout: '%s', started by '%c'"
          args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ]    

template switch for sending service call.

switch:
  platform: template  
  id: OvrHead
  optimistic: true
  on_turn_on:
    - homeassistant.service:
         service: switch.toggle 
         data: 
           entity_id: switch.overhead_door_barn_overhead 

text sensor

- platform: template
    name: Last User
    id: last_user
    icon: mdi:clock-start    

sensor

- platform: template
    name: Keypad Code
    id: keyCode    

I ran into this guy on discord and he made a whole esp program that basically replicates the manufacturer software. It was more than i needed but it’s pretty sweet.

Beyond what I pasted above for the esp card reader, I’m just using a simple automation to toggle a button for two seconds using another esp. This was previously 100% functional, repeatedly using my combination of arduino to read teh card, then passing via serial to an esp which pumped the code into HA where an automation would handle the rest.

It took some work, but using your example I’ve managed to successfully eliminate the external automation and have the esp repeatedly trigger a door lock from card reads. I figured there was a better way to accomplish this task but unfortunately getting there on my own without some direction was quite a struggle.

There is still one small problem remaining, however. At this point, ANY successful card read, regardless of the ID number will trigger the unlock sequence.

text_sensor:
  - platform: template
    name: Last User
    id: last_user
    icon: mdi:clock-start 
wiegand:
  - id: reader
    d0: D1
    d1: D2
    on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - homeassistant.event:
          event: esphome.wiegand_key_code
          data:
            key_code: !lambda "return x;"
      - lambda: |-
          if (x == "9919228"); {            
          id(frnt_door_lock).toggle();
          }

switch:
  platform: template
  id: frnt_door_lock
  turn_on_action:
    - homeassistant.service:
        service: lock.unlock
        data:
          entity_id: lock.front_door_lock_2

Logging return from the esp:

[01:12:19][D][wiegand:073]: received 26-bit tag: 7953630
[01:12:19][I][TAG:037]: received tag 7953630
[01:12:19][D][switch:020]: 'frnt_door_lock' Toggling ON.

Clearly tag 7953630 is not defined in the yaml anywhere to perform any actions.

I’m by far a c++ expert but looking at your lambda, I think the issue is your “if” statement and the action are inline and not indented under the “if” it’s treating the .toggle as a standalone statement to do on any tag scanned instead of only “if” x=“9919…” Try it like this.

on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
      - homeassistant.event:
          event: esphome.wiegand_key_code
          data:
            key_code: !lambda "return x;"
      - lambda: |-
          if (x == "9919228"); {            
            id(frnt_door_lock).toggle();
          }

Unfortunately correcting that indent did not resolve the issue, and any successful read regardless of the ID number will trigger the action. Went back through the esphome lambda documentation and tried multiple different ways to add an “else” action or some other method of doing the if statement, none of which would either compile or worked successfully. Pretty much at a loss here, sadly.

Edit:

Did a little more looking around google for how others have used esphome wiegand, I found someone doing essentially what I started with using HA native automations to do the legwork. In that, was also a workaround to my original issue of not taking the same card read twice in a row by adding this right after publishing the card number to HA:

      - delay: 2s
      - text_sensor.template.publish:
          id: rfid_tag
          state: '0000000'

so I guess that works, for now. Clearly doing it all in the ESP yaml is the better method, but I’m apparently not experienced with lambda if statements to make it happen.

Hello everyone, I’m asking if you can help me find the error in what I’m doing. I have a car gate and a pedestrian gate for the entrance to my house, each controlled by a Wiegand reader connected to an ESP32. I’ll share the ESPHome code for better understanding:

esphome:
  name: lectores-frente
  friendly_name: lectores-frente
  comment: IP 192.168.10.123

esp32:
  board: esp32dev
  framework:
    type: arduino
    version: recommended

# Enable logging
logger:
# Enable Home Assistant API
api:
  encryption:
    key: ""
ota:
  password: ""
wifi:
  ssid: "privada"
  password: "privada1937"
  manual_ip:
    static_ip: 192.168.10.123
    gateway: 192.168.10.1
    subnet: 255.255.255.0
    dns2: 8.8.4.4
    dns1: 8.8.8.8
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ""
    password: ""
captive_portal:
switch:
  - platform: gpio
    name: "relay_autos"
    pin: GPIO33
    inverted: true
    id: relay_autos
    on_turn_on:
       - delay: 500ms
       - switch.turn_off: relay_autos
  - platform: gpio
    name: "relay_peatonal"
    pin: GPIO32
    inverted: true
    id: relay_peatonal
    on_turn_on:
       - delay: 7000ms
       - switch.turn_off: relay_peatonal
  - platform: restart
    name: ${hostname} restart
    id: restart_switch
text_sensor:   
  - platform: template
    name: "text_sensor_rfid_autos"
    id: text_sensor_rfid_autos
    update_interval: 1000h
    on_value:
      then:
        - homeassistant.tag_scanned: !lambda |-
            return x;
  - platform: template
    name: "text_sensor_rfid_peatonal"
    id: text_sensor_rfid_peatonal
    update_interval: 1000h
    on_value:
      then:
        - homeassistant.tag_scanned: !lambda |-
            return x;
wiegand:
  - id: wg_lector_autos
    d0: 34
    d1: 35
    on_tag:
      - lambda: ESP_LOGD("AUTOS", "received tag %s", x.c_str());
      - text_sensor.template.publish:
          id: text_sensor_rfid_autos
          state: !lambda 'return x;'
  - id: wg_lector_peatonal
    d0: 21
    d1: 19
    on_tag:
      - lambda: ESP_LOGI("PEATONES", "received tag %s", x.c_str());
      - text_sensor.template.publish:
          id: text_sensor_rfid_peatonal
          state: !lambda 'return x;'
  web_server:
  port: 80
  auth:
    username: 
    password: 

“Both readers read the cards correctly and send them to Home Assistant, but the problem is that I don’t know how to set up the automation so that the card read by reader ‘A’ only activates relay ‘A,’ and reader ‘B’ only activates relay ‘B.’”

I set up this automation in Home Assistant, but the issue is that the relay is triggered when a card is read by either of the two readers, and it shouldn’t work that way. If I add the other relay to the automation, both relays are activated, and I don’t know how to “separate” them. Thanks.

alias: LECTOR FRENTE - AUTOS
description: ""
trigger:
  - platform: tag
    tag_id: "xxxxxx3416"
  - platform: tag
    tag_id: "xxxxxxx93477"
  - platform: tag
    tag_id: "xxxxxxxx3439"
  - platform: tag
    tag_id: "xxxxxxxx9116"
  - platform: tag
    tag_id: "xxxxxxx81535"
  - platform: tag
    tag_id: "xxxxx8628"
  - platform: tag
    tag_id: "xxxxx74725"
  - platform: tag
    tag_id: "xxxxx099"
  - platform: tag
    tag_id: "xxxxx68709"
  - platform: tag
    tag_id: "xxxxx90303"
  - platform: tag
    tag_id: "xxxxx6227"
condition: []
action:
  - if:
      - condition: numeric_state
        entity_id: sensor.lectores_frente_text_sensor_rfid_autos
        above: 10
    then:
      - type: turn_on
        device_id: 09af74c67377ecdef802f81a55d8da37
        entity_id: 92ebdab94599360bb135e0b7c314e5c9
        domain: switch
mode: single

You may wish to format your YAML code.
Place three back-tick quotes before the code, and three more below the code.

Thanks, this did the trick for me!!
Next up, I want to use some NFC stickers to create some tags. But I’m stuck with it; any suggestions on how to create your own tags, any Android app to write them?

Can anyone suggest what am I doing wrong? I have purchased one of Wiegand 26 output readers from aliexpress, does not seem to have any switch to set to wiegand output mode, also manual suggests there is no such thing, so I assume it is by default. I have hooked it up on 12V source, step down to 5V to power my ESP. I have wired only keypad with +12V and G, ESP is 5V and G (both sharing the same G) and connected D0 and D1 wires (green and white) directly to GPIOs 34 and 35

My esphome yaml is basically this:

wiegand:
  - id: mykeypad
    d0: GPIO34
    d1: GPIO35
    on_key:
      - lambda: ESP_LOGI("KEY", "received key %d", x);
    on_tag:
      - lambda: ESP_LOGI("TAG", "received tag %s", x.c_str());
    on_raw:
      - lambda: ESP_LOGI("RAW", "received raw %d bits, value %llx", bits, value);

However I cannot get any output after any keypress. If I swap wires, same no output. The only output I get is when I disconnect and connect either D0 or D1, but the output is as follows:

[23:44:23][I][RAW:041]: received raw 242 bits, value ffffffffffffffff
[23:44:23][D][wiegand:116]: received unknown 242-bit value: ffffffffffffffff
[23:44:34][I][RAW:041]: received raw 15 bits, value ffffffffffffffff
[23:44:34][D][wiegand:116]: received unknown 15-bit value: ffffffffffffffff
[23:44:36][I][RAW:041]: received raw 132 bits, value ffffffffffffffff
[23:44:36][D][wiegand:116]: received unknown 132-bit value: ffffffffffffffff
[23:44:37][I][RAW:041]: received raw 24 bits, value ffffffffffffffff
[23:44:37][D][wiegand:116]: received unknown 24-bit value: ffffffffffffffff
[23:44:37][I][RAW:041]: received raw 252 bits, value ffffffffffffffff
[23:44:37][D][wiegand:116]: received unknown 252-bit value: ffffffffffffffff
[23:44:38][I][RAW:041]: received raw 239 bits, value ffffffffffffffff
[23:44:38][D][wiegand:116]: received unknown 239-bit value: ffffffffffffffff
[23:44:39][I][RAW:041]: received raw 234 bits, value ffffffffffffffff
[23:44:39][D][wiegand:116]: received unknown 234-bit value: ffffffffffffffff
[23:44:39][I][RAW:041]: received raw 215 bits, value ffffffffffffffff
[23:44:39][D][wiegand:116]: received unknown 215-bit value: ffffffffffffffff
[23:44:39][I][RAW:041]: received raw 164 bits, value ffffffffffffffff
[23:44:39][D][wiegand:116]: received unknown 164-bit value: ffffffffffffffff
[23:44:43][I][RAW:041]: received raw 210 bits, value 0
[23:44:43][D][wiegand:116]: received unknown 210-bit value: 0
[23:44:45][I][RAW:041]: received raw 35 bits, value 0
[23:44:45][D][wiegand:116]: received unknown 35-bit value: 0
[23:44:46][I][RAW:041]: received raw 171 bits, value 0
[23:44:46][D][wiegand:116]: received unknown 171-bit value: 0
[23:44:47][I][RAW:041]: received raw 3 bits, value 0
[23:44:47][D][wiegand:116]: received unknown 3-bit value: 0
[23:44:47][I][RAW:041]: received raw 134 bits, value 0
[23:44:47][D][wiegand:116]: received unknown 134-bit value: 0
[23:44:48][I][RAW:041]: received raw 169 bits, value 0
[23:44:48][D][wiegand:116]: received unknown 169-bit value: 0
[23:45:04][I][RAW:041]: received raw 188 bits, value ffffffffffffffff
[23:45:04][D][wiegand:116]: received unknown 188-bit value: ffffffffffffffff

Anyone knows what am I doing wrong? Do I need to convert D0/D1 pins from reader to max. 3.3V before connecting them to ESP, since they output ~5V?

with mine I had to do a number of steps to put it in wiegand output mode. When it’s not, you’
ll get jibberish in the logs just like you are getting. If you are using an esp32, what does the data sheet say is the max voltage you can use on a gpio? If you use an esp8266 you can bypass a logic shifter as the gpios are 5v tolerant.

Thanks. The output I am getting is not from when i touch keys on reader. I get it when disconnecting do/d1 cables and connecting them back.
I looked at the board - there is only one jumper there and that is for relay (NO or push).
ESP32 says is 3.3V tolerant, but I am not sure if that applies to esp chip or complete board. However I did try using resistors as well and converting output to less than 3V, but that lead nowhere.

I asked seller to clarify but his responses are very slow

I’m not sure what the jumper has to do with anything. On mine it had to do a do a reset and then ground d0 or d1. Your getting jibberish because because your sending 5v to the gpio and it’s a logic High signal whether you push a button or not and it’s logic low ONLY when you power it off or disconnect the data wires. Your not sure if its the chip or the board? Neither is anyone else. Thats your responsibility to read the specs or data sheet to know how your board works and what voltages you can use on a gpio. Theres 100 different esp dev boards on the market and theyre not all the same, this is why you need to do your due diligence. Saying you are using an esp32 is meaningless and like telling your mechanic your “car” is broke and expecting him to tell you what parts you need to fix it.

Resistors limit current not voltage. You need to either switch to an esp8266 dev board, use a logic shifter, use a couple diodes or a couple transistors to drop the voltage. You also need to figure out if your reader comes in wiegand26 output by default or if it has the capability. I’ve seen some that do and others like mine that didn’t but can be put in that mode. If your product manual is as bad as mine, I feel for you!

Which reader do you have? You have a link?

The reader I purchased is this: https://www.aliexpress.com/item/1005001273071900.html

  • I mentioned jumper because I was looking at other similar readers, and these had reset jumper on the board. Mine does not. But like I said - I have contacted seller and am awaiting his response. I reached to the forum here just to see if someone may have already encountered this…
  • I used resistors to create the voltage divider that outputs lower voltage (safely below 3.3V) and that did not yield any fruit.
  • I also tried using Wemos D1 Mini and the behavior is the same.

At this point, I am thinking that reader is not configured as wiegand output device. Hoping for seller to get back to me and advise. Manual is not mentioning anything in that regard.

Is your 12VDC Negative/GROUND connected to BOTH the black GND and the grey COM wires?
The wiring diagram on that AliExpress page shows these both tied together.