How to send a signal through 2 wires using rmt.h ?

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

How to send a signal through 2 wires using rmt.h ?

Postby GeorgeFlorian1 » Thu Dec 12, 2019 2:20 pm

Board: ESP32-EVB
OS: Linux Mint

Hello !

For the past week, I have been trying to send this binary number: 01100000101111001011111000 through two wires, emulating the Wiegand Protocol, to a Card Reader.

Wiegand Protocol starts with both pins HIGH. When I send a 0, W0 pin is pulled LOW for usually 20-100us and W1 stays HIGH. When a 1 is being sent W1 is pulled LOW for usually 20-100us and W0 stays HIGH.

I have been able to send that number by doing this:

Code: Select all

void setup() {
  Serial.begin(115200);

  pinMode(W0, OUTPUT);
  pinMode(W1, OUTPUT);
  digitalWrite(W0, HIGH);
  digitalWrite(W1, HIGH);
  // ...
}
  
void loop() {
  delay(100);
  if(change) {
    Serial.println("Sending ID...");
    pulse = pulseWidth.toInt();
    portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
    portENTER_CRITICAL(&mux);
    for(int i = 0; i<26; i++) {
      if(wiegandArray[i] == 0) {
        digitalWrite(W0, LOW);
        delayMicroseconds(pulse);
        digitalWrite(W0, HIGH);
      } else {
        digitalWrite(W1, LOW);
        delayMicroseconds(pulse);
        digitalWrite(W1, HIGH);
      }
      delayMicroseconds(pulse);
    }
    portEXIT_CRITICAL(&mux);
  }

  if(change) {
    change = false;
    for(int i = 0; i<26; i++) {
      Serial.print(wiegandArray[i]);
    }
    Serial.println();
  }
}
The problem with this is that it isn't reliable. It won't work all the time.

I've then tried implementing it in a task:

Code: Select all

void taskOne(void * parameter ) {
  for( ; ; ) {
    if(change) {
      int pulse = pulseWidth.toInt();
      vTaskSuspendAll();
      for(int i = 0; i<26; i++) {
        if(wiegandArray[i] == 0) {
          digitalWrite(W0, LOW);
          delayMicroseconds(pulse);
          digitalWrite(W0, HIGH);
        } else {
          digitalWrite(W1, LOW);
          delayMicroseconds(pulse);
          digitalWrite(W1, HIGH);
        }
        delayMicroseconds(pulse);
      }
      xTaskResumeAll();
      if(change) {
        change = false;
        for(int i = 0; i<26; i++) {
          Serial.print(wiegandArray[i]);
        }
        Serial.println();
      }
      uxTaskGetStackHighWaterMark(NULL);
    } // if(change)
  } // for( ; ; )
}

void setup() {
  xTaskCreate(
              taskOne,          /* Task function. */
              "TaskOne",        /* String with name of task. */
              10000,            /* Stack size in bytes. */
              NULL,             /* Parameter passed as input of the task */
              1,                /* Priority of the task. */
              NULL);            /* Task handle. */
}

void loop() {
delay(100);
}
But this doesn't do anything.

Now, I am being told to try the RMT driver, that can only send one signal through one pin at a time, but I need one signal through two pins, which can apparently be done by doing this:
If you need to split the signal on the output you can do that via NPN/PNP transistors to create an inverse signal or direct the output to two outputs based on the high/low state of the single output.
But, I have no idea how to use transistors. Will I have to split the signal by 0 and 1 in code or from hardware ? How is the split happening ?

I want to send 01100000101111001011111000. Do I send it all at once with a little pause between each one of the bits and the transistor will split the signal and send the zeros (0) to a pin, the ones (1) to the other pin and hope that they will be synchronized ? Because I can't have 0 and 1 sent at the same time.

Can I get some help in understanding how this works and how can I implement it ?
Thank you.

tommeyers
Posts: 184
Joined: Tue Apr 17, 2018 1:51 pm
Location: Santiago, Dominican Republic

Re: How to send a signal through 2 wires using rmt.h ?

Postby tommeyers » Thu Dec 12, 2019 8:09 pm

Take a look here: https://www.arduinolibraries.info/libra ... nd-library

In the in file there is a readme that describes the protocol.

Maybe the code could be adapted to your project.

Tom Meyers
IT Professional, Maker
Santiago, Dominican Republic

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

Re: How to send a signal through 2 wires using rmt.h ?

Postby GeorgeFlorian1 » Fri Dec 13, 2019 8:56 am

tommeyers wrote:
Thu Dec 12, 2019 8:09 pm
Take a look here: https://www.arduinolibraries.info/libra ... nd-library

In the in file there is a readme that describes the protocol.

Maybe the code could be adapted to your project.

Tom Meyers
This is at the beginning of the readme:
# Yet Another Arduino Wiegand Library

A library to received data from Wiegand RFID Card readers.
All of the examples I could find are similar to this one. They are all Wiegand Readers/Receiver and I want a Wiegand Writer/Transmitter/Sender.

tommeyers
Posts: 184
Joined: Tue Apr 17, 2018 1:51 pm
Location: Santiago, Dominican Republic

Re: How to send a signal through 2 wires using rmt.h ?

Postby tommeyers » Fri Dec 13, 2019 2:04 pm

Goerge,

Oops, I read through that too quickly.

Here is another try an transmitting: https://www.codeproject.com/Articles/12 ... th-Arduino

I thought it would be necessary to invert the second line from the first. This shows how to wiggle each line in code.

Tom Meyers
IT Professional, Maker
Santiago, Dominican Republic

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

Re: How to send a signal through 2 wires using rmt.h ?

Postby GeorgeFlorian1 » Tue Dec 17, 2019 9:22 am

tommeyers wrote:
Fri Dec 13, 2019 2:04 pm
Goerge,

Oops, I read through that too quickly.

Here is another try an transmitting: https://www.codeproject.com/Articles/12 ... th-Arduino

I thought it would be necessary to invert the second line from the first. This shows how to wiggle each line in code.

Tom Meyers
I have already achieved the same results in my project:

Code: Select all

for(int i = 0; i<26; i++) {
      if(wiegandArray[i] == 0) {
        digitalWrite(W0, LOW);
        delayMicroseconds(pulse);
        digitalWrite(W0, HIGH);
      } else {
        digitalWrite(W1, LOW);
        delayMicroseconds(pulse);
        digitalWrite(W1, HIGH);
      }
      delayMicroseconds(pulse);
    }
The problem with this is that it won't work 100% of the time, because of the FreeRTOS scheduler that will interfere and can screw up the signal.

tommeyers
Posts: 184
Joined: Tue Apr 17, 2018 1:51 pm
Location: Santiago, Dominican Republic

Re: How to send a signal through 2 wires using rmt.h ?

Postby tommeyers » Tue Dec 17, 2019 9:08 pm

George i don't see the similarities with this code:
void outwiegbit(unsigned int b)
{
int sel = b == 0 ? W_D0 : W_D1;
digitalWrite(sel, 0);
delayMicroseconds(80);
digitalWrite(sel, 1);
delayMicroseconds(240);
}
You wiggle one or the other. This wiggles both at the same time. See what think.
Tom
IT Professional, Maker
Santiago, Dominican Republic

Who is online

Users browsing this forum: No registered users and 55 guests