Hello everyone,
I'm trying to emulate a 125Khz RFID card (0X010E8A7B00370027) and send it to a master device, replacing the same function as a Dallas DS1990A reader.
The card number is sent 1-wire to the master, but the master is unable to understand it.
Has anyone done something similar or have any tips?
#include <OneWire.h>
#define ONE_WIRE_BUS 16 // Pin 16 of ESP32
OneWire ds(ONE_WIRE_BUS);
// HID card data (Family Code, ID, and CRC) - 0X010E8A7B00370027
byte ibutton[8] = { 0x01, 0x0E, 0x8A, 0x7B, 0x00, 0x37, 0x00, 0x27 };
void setup() {
Serial.begin(115200);
pinMode(ONE_WIRE_BUS, OUTPUT); // Sets the pin as output initially
}
void loop()
{
// Simulate iButton presence
Serial.println("Sending presence pulse...");
sendPresencePulse();
delayMicroseconds(200);
// Wait for master's reset
if (waitForMasterReset())
{
// Send presence pulse
sendPresencePulse();
// Wait for master's command
byte command = readByte();
Serial.print("Command received: 0x");
Serial.println(command, HEX);
// Send family code and ID (LSB first)
Serial.println("Sending family code and ID...");
for (int i = 0; i < 7; i++)
{
Serial.print("Sending byte: ");
Serial.println(ibutton[i], HEX);
ds.write(ibutton[i]); // Send 7 bytes
}
// Send CRC
Serial.print("Sending CRC: ");
Serial.println(ibutton[7], HEX);
ds.write(ibutton[7]); // Send CRC
delay(3000); // Wait before sending the next cycle
}
}
// Generate reset on the 1-Wire bus
void generateReset() {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(240); //560 // Adjusted to 560us
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(240); //55 // Correct time to wait for the presence pulse
}
// Send presence pulse
void sendPresencePulse() {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(136); // Adjusted to 136us
pinMode(ONE_WIRE_BUS, INPUT);
delayMicroseconds(410); // Kept as per the table
}
// 1-Wire protocol bit write/read function
void writeBit(int bit) {
pinMode(ONE_WIRE_BUS, OUTPUT);
digitalWrite(ONE_WIRE_BUS, LOW);
delayMicroseconds(6); // Wait 6us
if (bit == 1) {
pinMode(ONE_WIRE_BUS, INPUT); // Release the line
} else {
// Keep the line low to write 0
delayMicroseconds(9); // Wait another 9us
}
delayMicroseconds(55); // Total slot time of 60us
pinMode(ONE_WIRE_BUS, INPUT); // Release the line
}
// Function to wait for master's reset
bool waitForMasterReset() {
// Wait for the line to be pulled LOW by the master
while (digitalRead(ONE_WIRE_BUS) == HIGH) {
// Wait
}
unsigned long startTime = micros();
// Master keeps the line LOW for 480us (tRSTL minimum 480us)
while (digitalRead(ONE_WIRE_BUS) == LOW) {
// Wait
}
unsigned long resetDuration = micros() - startTime;
// Check if the reset time is valid
if (resetDuration >= 480) {
Serial.println("Reset detected.");
return true;
} else {
Serial.println("Invalid reset.");
return false;
}
}
// Read a byte from the master
byte readByte() {
byte value = 0;
for (int i = 0; i < 8; i++) {
value |= (readBit() << i); // LSB first
}
return value;
}
// Read a bit from the master
int readBit() {
// Master initiates the slot time by pulling the line LOW
while (digitalRead(ONE_WIRE_BUS) == HIGH) {
// Wait
}
delayMicroseconds(15); // Wait 15us
int bit = digitalRead(ONE_WIRE_BUS); // Read the bit
// Wait for the slot time to finish (minimum 60us per slot)
unsigned long startTime = micros();
while ((micros() - startTime) < 60) {
// Wait
}
return bit;
}