Electronic – arduino – Logic Analyzer shows voltage change in analog but not digital

arduinologic analyzersaleae-logic-analyzer

While using a logic analyzer with analog voltage to test Digital Output Pin voltages on an Arduino UNO, I am seeing the expected digital output and analog output (HIGHs and LOWs for digital and 5V to approx. 0V for Analog).

I'm using a Saleae logic 4 to test the digital output of an Arduino and an Arduino-compatible (Ruggeduino) for simple digital output. The Arduino seems to run my sketch just fine and the Saleae can read my output pin as both digital and analog. The moment, however, I drop the "Ruggeduino" in with the same sketch, my digital output seems to fail to work, and when I take another sample with the Saleae, my "Analog" voltage shows the highs and low voltages I'm expecting, but the "Digital" output is suspiciously blank.

Why would my logic analyzer show the expected digital and analog output when testing the Arduino Uno, but show a consistent "High" for digital output but both high and low voltages on the Analog output when testing the Ruggeduino?

Additional Information: Devices used:

Edit: Not satisfied to just sit and wait for someone to answer, I did some more digging. Here's what I found out:

  • The logic appears "High" despite the change in voltage, looking as if it's stuck High
  • The Analog voltage of "Low" for the output pins appears to be 1.586V, which falls outside the range of TTL "LOW" (and most likely the cause of the "stuck" logic level)
  • This only happens when the pins are connected to the downstream input pins that should only be listening for digital output. Once you remove the downstream pins from the equation, the "LOW" voltage drops back down to just above 0V.

I don't currently have a screenshot handy to upload, but I can upload my sketch to show what I'm attempting to do:

void writeWiegand(String);
int outZeroPin = 6;
int outOnePin = 7;
int led = 13;


void setup() {
  pinMode(outZeroPin, OUTPUT);
  digitalWrite(outZeroPin, HIGH);
  pinMode(outOnePin, OUTPUT);
  digitalWrite(outOnePin, HIGH);
  Serial.begin(9600);
  delay(1000);

}


void loop() {
  String code = "0001001001100101100000001011010010";
  writeWiegand(code);
  delay(500);


}

void writeWiegand(String code) {
  for (int i = 0; i <= (code.length() - 1); i++) {

    if (code.charAt(i) == '0') {
      digitalWrite(outZeroPin, LOW);
      //delayMicroseconds(100);
      delay(100);
      digitalWrite(outZeroPin, HIGH);
      Serial.print(code.charAt(i));
    } else {
      digitalWrite(outOnePin, LOW);
      //delayMicroseconds(100);
      delay(100);
      digitalWrite(outOnePin, HIGH);
      Serial.print(code.charAt(i));
    }
    //delayMicroseconds(100);
    delay(100);
  }
  digitalWrite(led, LOW);
  Serial.println(" Output to Wiegand");
}

Edit 2: The downstream device is a proprietary Access Control Panel, and the input pins are pins are for Wiegand communication with a card reader. Since it is proprietary, I'm not sure what I'm legally allowed to share. According to the manufacturer, the two input pins output 5V which the reader is supposed to Pull to ground to send information on either the "Zero" or "One" wire. The UNO R3 works fine for this task with the same code above. When pulling low with the Ruggeduino, there is still 1.586V left over, which I find confusing.

Best Answer

Since it is proprietary, I'm not sure what I'm legally allowed to share. According to the manufacturer, the two input pins output 5V which the reader is supposed to Pull to ground to send information on either the "Zero" or "One" wire.

I suspect that they have a strong (i.e. low-value) pull-up resistor to +5 V on these "input" pins, and that is enough cause a significant voltage drop across the 220 Ω input protection PTC resistor on the Ruggeduino-SE, when the MCU attempts to pull that I/O pin low.

Ruggeduino I/O pin protection components:

Ruggeduino I/O pin protection

Source:http://www.rugged-circuits.com/ruggeduino-1

A quick calculation is that a 470 Ω pull-up to +5 V in the device, in conjunction with the 220 Ω input protection PTC resistor on the Ruggeduino-SE, would result in approx. 1.5 V at the actual Ruggeduino-SE "connector terminal" in the above diagram, when the MCU (i.e. "Microcontroller Pin" in the above diagram) tries to pull that pin down to 0 V.


To test this hypothesis, temporarily short (i.e. bridge across) the 220 Ω resistor for one of the output pins you are using on the Ruggeduino. That will directly connect the MCU pin, to the output connection terminal. See if the measured voltage at the output connection then drops to approx. 0 V for logic 0 output, when connected to this proprietary Access Control Panel input.

According to this Ruggeduino-SE page:

"If you do have an application where this built-in 220 ohm resistance is not wanted, you can easily change it. Every I/O pin has through-hole pins surrounding its PTC fuse that can be jumpered with either a wire for 0 resistance or with a standard resistor. Here is a picture showing how to bypass the 220 ohm PTC for pin D7."

Ruggeduino bypass 220R PTC

[Updated to refer to the 220 Ω resistor as a 220 Ω PTC resistor, as described on the Ruggeduino-SE according to the page linked in the original question.]


After a quick bit of research, it seems that devices using the Wiegand interface usually have open-collector outputs; have a pull-up resistor to some voltage, typically at the input device (that fits with the earlier hypothesis); the voltage for the pull-up resistors is sometimes +5 V, but sometimes higher.

Potential solution

More research would be needed (although out-of-scope for this specific answer), but based on what I have read, I would simply add open-collector drivers (either BJT NPN or MOSFET N-channel) to the two Ruggeduino outputs (i.e. the "Connector Terminal" pins) used for the Wiegand interface outputs.

In that way, the 220 Ω PTC resistors on the Ruggeduino are not in the external current path, and therefore they would no longer form a potential divider with the pull-up resistor in the external device. Using open-collector drivers in this way would allow the outputs to reach (close to) 0 V, and so would resolve the originally stated problem.

Note: Adding open-collector drivers would have the side-effect of inverting the polarity of the MCU output, i.e.:

  • MCU pin high = open-collector driver "on" = open-collector output low
    (the open-collector output is actively pulled toward 0 V)
  • MCU pin low = open-collector driver "off" = open-collector output effectively high
    (the output is not actively driven and is pulled-up by the external resistor)

This behaviour would need to be considered in the MCU firmware.