Emulate 1-wire Slave

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;
}

Your code at the top says "ESP32", is that what you have?
If so it's running an RTOS therefore I would be surprised if any of the microsecond delay timings match up with the actual output. Check with an oscilloscope. As to whether you are sending the correct bit pattern, that is whole separate issue that I don't know anything about.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.