Door - Leaving keys behind
Having a badge scanner on every door is one of the more interesting parts of living on a college campus. Unfortunately, the door to my dorm room did not come with a badge reader when I moved in. Here is how I fixed the problem for twelve dollars.
Parts
RBE Department cleanout
- CTRE VRM, used as a 12v to 5v buck converter
- CTRE Talon SR, a PWM DC motor controller
- CIM, a brush motor
WPI CollabLab
- 12v 5a DC power supply
- HID R40 RFID badge reader
- 57kΩ & 100kΩ resistors
- 22 gauge wire
- wire nuts
- hose clamps
roommate
- blu-tack adhesive
- 16 lb command strips
roommate’s sister
- 2200mAh usb power bank
personal collection
- usb a cable
micro center (asked for money)
- 2x pi pico w ($6)
Hardware design
The system has two components, a R40 badge reader on the outside of the door to identify users, and a winch on the inside to unlatch it.
For ease of installation, R40s attach to a mounting plate such that when installed only one screw is visible. Fortunately, the gap between the R40 and its mounting plate are sufficient to fit a pico w and a pair of voltage dividers to convert the 5v data lines from the R40 to 3.3v. Both the R40 and pico can run off of five volts, so they can share a USB power supply.

Sketch of the circuitry, the resistors are 100 and 57 kΩ
On the inside of the door is a winch attached to a network addressable control system.
Software design
R40 badge readers implement the wiegand interface for transmitting badge numbers.
Two pins are involved, data one and data zero. Both are high (5v) by default and are pulled low for a short amount of time to indicate their respective bit. Ideally you detect the end of a transmission based on the number of bits sent (same for every card of a given type), but for maximum compatibility I use a timeout.
Once the outside of the door has a badge number, it sends a TCP packet to the inside of the door, where it is then checked.
This method of verifying badges is very vulnerable to a replay attack. Instead of worrying about that, I’m relying on the security of having both devices on a private WPA2 network.
Because the system uses asynchronous rust, the winch controller can spawn a task to open the door without blocking other operations.
async fn open_door(mut pwm_c: &mut pwm::Config, mut pwm: &mut Pwm<'_>) {
run_motor(&mut pwm_c, &mut pwm, 0x13DF); // up
Timer::after_millis(3000).await;
run_motor(&mut pwm_c, &mut pwm, 0x123C); // down
Timer::after_millis(750).await;
run_motor(&mut pwm_c, &mut pwm, 4687); // stop
}
Fate
Unfortunately, this iteration of the system was not received well by my school. A few days after installation, I was given a deadline to remove the system for “tampering with existing room locking devices”. I did not have the opportunity to do so because it was stolen the following Saturday between 1 and 2 AM.