Wiegand protocol RFID readers known to work with ESPHome?

Hi, the code you are using works on esp32? Did you try it?

No, an ESP32 is overkill for just a reader. ESP8266 works wonderfully, and can also drive relays to light the leds, if you so choose. Why spend more and require more space when a Wemos D1 Mini works so well?

Because i would like to use an ESP32 Cam with the double function of Cam and Wiegand Reader. It would be a wonderful solution…
You said “no” because you are sure that it don’t work on esp32?

I’m fairly certain some of the code is rather specific to the ESP8266, preventing it from being used properly on an ESP32. Best way to find out is to try it. I understand your use case, and agree, updating the code to execute properly on ESP32 would be good for everyone.

I just reviewed the original gdoerr code from github and he has this in his comments, very near the top of the code:

 * In my example, hooked to an Olimex ESP32-POE device connected to a Retekess H1EM-W
 * Wiegand keypad. This device calls a service on Home Assistant when a code is available

So it appears it SHOULD work for you on an ESP-32-CAM module. :partying_face:

Do understand, the handling of interrupts and their interrupt handler routines is somewhat different on ESP32, so there is always the potential it COULD require some changes. Be certain to refer to gdoerr’s original code for these areas.

Further down the Github thread, skylord123 posted his code gist which definitely runs on the ESP32. Note well, his comments regarding power supplies. Low-grade, under-powered, or poor quality power supplies cause problems.

1 Like

Tonight I received a pair of new AI-Thinker styled ESP32-CAM boards. In attempting to add the Wiegand_device.h code, I encountered compilation errors, specifically around variable references during the interrupt routines ReadD0() and ReadD1().

This is where I must admit, I am not any kind of an experienced C++ developer. Just a hacker who is decent with a lot of different things. I’m a bit stumped, because I’m fairly certain the interrupt routines must be static code. How to reference the volatile class variables in a manner that doesn’t throw these ‘dangerous relocation’ errors is what remains to be discovered.

Maybe a better C++ developer can help educate us. :slightly_smiling_face:

/data/esp32cam-wiegand/.pioenvs/esp32cam-wiegand/src/main.cpp.o: In function `WiegandReader::ReadD1()':
/config/esphome/.esphome/build/esp32cam-wiegand/src/esphome/components/api/api_pb2.h:689:(.iram1.20[WiegandReader::ReadD1()]+0x3): dangerous relocation: l32r: literal placed after use: .literal._ZN13WiegandReader6ReadD1Ev

Thanks to reddit user samguyer, removing the ICACHE_RAM_ATTR and/or IRAM_ATTR designations from the interrupt routine declarations resolved the issue. It compiles successfully now with no warnings. I’ll keep working on this tomorrow, and follow-up then. :slight_smile:

Well, it may compile and link successfully, but it doesn’t run properly on the ESP32-CAM. :frowning:

Added the following compile flags to the YAML:

  platformio_options:
    build_flags: 
    - -mtext-section-literals

While these DO successfully avoid the dangerous relocation errors, the code does not function successfully on the ESP32-CAM. Still looking…

Unfortunately, I have to dedicate more of my off hours to other efforts around the house. There are a limited number of GPIO pins available for use on the ESP32-CAM board. You can either re-purpose those used for the SD card, or those used for the UART. But I’ve not been able to get past the l32r: dangerous relocation error today.

Back to my earlier statement: maybe someone better at C++ and ESPHome can help here.

1 Like

Great news, everyone! (Futurama reference for the unknowing…)

How this isn’t plastered all over this community forum is entirely beyond my understanding. :crazy_face:

I’ll be downloading and testing this custom component tonight.
Someone else please post a comment so I can add another post later?

1 Like

As I said on Discord, this works for me :slight_smile:
(here’s your comment :wink: )

1 Like

And don’t thank me, thank @ssieb for the code, and @nejccc for the pointer to the code!!

It is possible in more detail how what and where to do with this code?

You can either:
a) download the code from Github (linked above) and place it on your HA server in the directory homeassistant/esphome/custom_components, then use it in your YAML
b) Use the Github link in your YAML to download the code every time you rebuild your ESPHome device.

Samuel has provided examples on his Github page of everything.

sorry newbie) Show code for example)

  1. Go to SSieb’s github link.
  2. Click down to the directory ssieb/custom_components/wiegand/
  3. Ignore the file README.md - that’s the web page text you’re seeing beneath the files list - it doesn’t compile
  4. Click on each of these three file links:

and save the files to your local PC/desktop/laptop/Mac/whatever. Then upload the files (if you’re on Windows, WinSCP is great for this) to your Home Assistant system, in the path /???/???/homeassistant/esphome/custom_components/wiegand/

Once the python, .h, and .cpp file are present on the Home Assistant system, edit your ESPHome device YAML file like so:

wiegand:
  - id: reader
    d0: 4
    d1: 5
    on_tag:
      - lambda: ESP_LOGD("TEST", "received tag %s", x.c_str());

id is your ESPHome device name/id
d0: 4 indicates you’re using Pin 4 on your ESP for the Data0 line from the Wiegand reader (Green wire)
d1: 5 indicates you’re using Pin 5 on your ESP for the Data1 line from the Wiegand reader (White wire)

Don’t forget to connect your GND/COM black wire from the Wiegand device to the ESP8266 or ESP32 device, or your signals will never be seen. :wink:

On my Ai-Thinker clone ESP32-CAM, when adding the Wiegand custom component, the camera fails to initialize. I’ve designated GPIO 12 and GPIO 13 for the Wiegand data lines. I chose these because they are exposed on the ESP32-Cam device, and only used for the SD card, which isn’t used by ESPHome.

[15:36:01][I][logger:214]: Log initialized
[15:36:01][C][ota:461]: There have been 0 suspected unsuccessful boot attempts.
[15:36:01][D][esp32.preferences:114]: Saving preferences to flash...
[15:36:01][I][app:029]: Running through setup()...
[15:36:02][E][camera.c:1327] camera_init(): gpio_install_isr_service failed (105)
[15:36:02][E][camera.c:1406] esp_camera_init(): Camera init failed with error 0x105
[15:36:02][E][esp32_camera:024]: esp_camera_init failed: ESP_ERR_NOT_FOUND
[15:36:02][E][component:112]: Component esp32_camera was marked as failed.

Here’s the YAML output:

[15:36:06][C][logger:233]: Logger:
[15:36:06][C][logger:234]:   Level: DEBUG
[15:36:06][C][logger:235]:   Log Baud Rate: 115200
[15:36:06][C][logger:236]:   Hardware UART: UART0
[15:36:06][C][wiegand.text_sensor:059]: Wiegand reader:
[15:36:06][C][wiegand.text_sensor:060]:   D0 pin: GPIO12
[15:36:06][C][wiegand.text_sensor:061]:   D1 pin: GPIO13
[15:36:06][C][esp32_camera:048]: ESP32 Camera:
[15:36:06][C][esp32_camera:049]:   Name: esp32cam
[15:36:06][C][esp32_camera:050]:   Internal: NO
[15:36:06][C][esp32_camera:052]:   Data Pins: D0:5 D1:18 D2:19 D3:21 D4:36 D5:39 D6:34 D7:35
[15:36:06][C][esp32_camera:053]:   VSYNC Pin: 25
[15:36:06][C][esp32_camera:054]:   HREF Pin: 23
[15:36:06][C][esp32_camera:055]:   Pixel Clock Pin: 22
[15:36:06][C][esp32_camera:056]:   External Clock: Pin:0 Frequency:20000000
[15:36:06][C][esp32_camera:057]:   I2C Pins: SDA:26 SCL:27
[15:36:06][C][esp32_camera:058]:   Reset Pin: -1
[15:36:06][C][esp32_camera:088]:   Resolution: 1600x1200 (UXGA)
[15:36:06][E][esp32_camera:095]:   Setup Failed: ESP_ERR_NOT_FOUND
[15:36:06][C][psram:020]: PSRAM:
[15:36:06][C][psram:021]:   Available: YES

and the actual ESPHome YAML code:

esphome:
  name: esp32cam-wiegand
    
esp32:
  board: esp32dev
  framework:
    type: arduino
    version: recommended

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: **redacted**

wifi:
  ssid: IOT
  password: **redacted**

# Example configuration entry
esp32_camera:
  name: esp32cam
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  resolution: UXGA
  
wiegand:
  - id: reader
    d0: 12
    d1: 13
    on_tag:
      - lambda: ESP_LOGD("TEST", "received tag %s", x.c_str());
2 Likes

thank you very much!!!

The good news is, this custom component by ssieb is working well with my Retekess keypad/tag reader on the ESP32-CAM device. It just wasn’t initializing the camera properly. I’ve switched from IO12 and IO13 to IO14 and IO15, but it still fails to init the camera device. I suspect it may be a power supply issue, where my USB port isn’t providing enough power for the ESP32CAM to initialize properly.

ESPHome complained about strapping pins if I used either IO12 or IO15 so I switched to IO13 and IO14. Camera still does not initialize properly, even at 800x600 resolution, with the 5V 3A power supply. :frowning: :frowning:

I also tried removing the HOT keyword from the two Wiegand interrupt service routines (ISRs) but it did not help. It does still read tags correctly without this HOT keyword. I’ll definitely put it back, as if @ssieb wrote it that way, I trust it is correct.

1 Like

or instead of doing steps 1 to uhh… saving files, uploading etc, just paste this in your config:

external_components:
  - source: github://ssieb/custom_components
    components: [ wiegand ]
    refresh: 15min
2 Likes

Next steps: Discussing with ssieb and possibly Otto Winter any possible causes for incompatibility between ESP32CAM OV2640 camera code and the (very function yet still minimal) Wiegand code from ssieb.

These discussions take place on the ESPHome Discord, if anyone is ever interested.

I’ve just reviewed the source code for the ESP32 camera in ESPHome, and at first glance there does not appear to be any reason whatsoever for any incompatibility between it and Wiegand protocol handling. Wiegand uses two data pins and ISRs, camera uses many I2C data pins and no ISRs except for any possibly built into low-level I2C communication. /me scratches head . . :upside_down_face:

In the file esp32_camera.cpp, the camera’s setup priority is established:

float ESP32Camera::get_setup_priority() const { return setup_priority::DATA; }

I believe if we initialize the Wiegand component AFTER the camera, it may work properly. Will try to find out today… The next step after DATA is PROCESSOR.

2 Likes

Unfortunately, I have some BAD NEWS for everyone reading and interested. :frowning:

The ESP32-Cam modules and low-level initialization code for the camera inject their own ‘special’ interrupt handling on the ESP32 processor, which prevents ESPHome’s (Arduino) interrupts from processing properly. :frowning: I’ve included a link below describing the source of the error 105 that is occurring on the ESP32Cam board whenever the Wiegand code is loaded. @ssieb commented below. I bolded one part of his comments.

ESP32 CAM: gpio_install_isr_service failed (105) - ESP32 Forum
seems there are ISRs in the ESP32 camera_init routine (where this error 105 is occurring) that may be the source of the issue.

## ssieb Today at 2:33 PM
Ah, that’s terrible. Looks like they won’t be compatible…

The espcam is incompatible with any normal interrupt use. You would probably have the same problem if you used a rotary encoder for example.

1 Like

Hi everyone
Just getting ready to play with Wiegand. How do you use the component to get the keypad code? Unit I am getting has the card and code

Hi Fred,
i am not able to install the firmware.
Always same error : “Component not found: wiegand.”
My ESP`s. All working well :


My .yaml :

custom_components folder with wiegand files:

Error Message !:

Guten abend, @kepir !! :slight_smile:

Follow @nejccc example a few posts above, using the github link.