My output pins seem to be functioning as pulldowns for my inputs.

Hello,

I have a project which tests for correct wiring of 3-pin XLR microphone cables by setting a pin high on one end, reading what is high or not on the other end, setting the output low again, and repeating for all pins.

As I am reading input pins which are high impedance I was concerned about floating voltages causing a pin to read as high when it was either disconnected or not being driven high by the corresponding output.

To test the effect of this I connected an XLR connector to three analog pins* which I set as input, and used serialprint to allow me to read the values appearing on them. As expected, floating voltages were a problem with no pulldown resistors, though I was surprised to see the pins reading the full 5 volts (1023) when a 20M cable was connected at one end only. Also as expected, the 5.1K pulldowns supressed these voltages to 5mV max (1).

I cannot attach my .ods file, but with no pulldows I was seeing a max of about 15mV (5) when connected to low outputs.

What I don't understand is why connecting the other end of the cable to output pins which where set low was also effective in suppressing the floating voltages without any pulldowns. Is this due to the low impedance of the outputs?

I will need to use external pulldowns anyway as an open connection would still cause a problem, I am just asking out of interest.

*Was it safe to assume that analog inputs have the same input impedance as digital inputs and will be similarly effected by floating voltages?

Thanks,

Chris

Need to see a wiring diagram and your code. How to post your code in the Arduino forum: See item nr. 7 in this link; http://forum.arduino.cc/index.php/topic,148850.msg1118324.html#post_codetags Or: After you have typed your message, start the Arduino IDE if not already running and load or type in your code. Right click in the editor window then left click [Select All]. Right click again then left click [Copy]. And type:

[code]

Type or paste your code here

[/code]

Chris935: What I don't understand is why connecting the other end of the cable to output pins which where set low was also effective in suppressing the floating voltages without any pulldowns. Is this due to the low impedance of the outputs?

Chris, that is almost like asking "I just don't understand why when I put water all over myself that I get wet". That's gotta be the expected result doesn't it? It's kind of the definition of what being wet is.

Similarly, when you connect the other end of the cable to an output, then that particular cable is not longer floating. This is basically the definition of what floating (or not floating) is.

Chris935: I cannot attach my .ods file

Why not? Just export as an image and post it here.

Chris935: What I don't understand is why connecting the other end of the cable to output pins which where set low was also effective in suppressing the floating voltages without any pulldowns. Is this due to the low impedance of the outputs?

Are you surprised that driving a cable low forces the voltage down? If you drive it either high or low it's of course no longer floating....

Chris935: I will need to use external pulldowns anyway as an open connection would still cause a problem, I am just asking out of interest.

Or pull up, doesn't really matter.

But if you test long cables as you do I would add some protection. Because when you said you read 5V aka 1023 you probably didn't read 5V and the voltage was probably even higher ;) And it's a bit easier to use pull up then. I would use a 1k pull up and a 100nF cap to GND. And from there a 100k to the pin.

Chris935: *Was it safe to assume that analog inputs have the same input impedance as digital inputs and will be similarly effected by floating voltages?

Both are indeed high but the analog impedance is lower. That's why for example it's a bad idea to read a pot of 1M, reading it will effect it.

Thank you all.

stuart0:
Chris, that is almost like asking “I just don’t understand why when I put water all over myself that I get wet”. That’s gotta be the expected result doesn’t it? It’s kind of the definition of what being wet is.

Similarly, when you connect the other end of the cable to an output, then that particular cable is not longer floating. This is basically the definition of what floating (or not floating) is.

I think my issue is that I don’t understand what’s happening electrically when an input or output is written high or low in the code.

I had imagined high as being equivalent to connecting the 5V source to the pin through a series resistor representing the pins impedance, and low as being the absence of the 5V. Reading these replies it seems as though writing the pin low essentially connects it to 0V via the pin impedance, (an “active” low rather than a “passive” low) is this correct?

My code for reading the analog pins is as follows;

“Screen” refers to the outer screen conductor while “hot” and “cold” are the differential signal conductors.

int ScreenSource = 5;                       
int HotSource = 6;
int ColdSource = 7;

void setup() {
  // put your setup code here, to run once:

pinMode(ScreenSource, OUTPUT);
pinMode(HotSource, OUTPUT);
pinMode(ColdSource, OUTPUT);

digitalWrite(ScreenSource, LOW);
digitalWrite(HotSource, LOW);
digitalWrite(ColdSource, LOW);

  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:

 int ScreenFloat = analogRead(A4);
 int HotFloat = analogRead(A5);
 int ColdFloat = analogRead(A6);

 Serial.print("Screen value follows, ");
 Serial.println(ScreenFloat);
 Serial.print("Hot value follows, ");
 Serial.println(HotFloat);
 Serial.print("Cold value follows, ");
 Serial.println(ColdFloat);
 delay(10);

}

I have copy and pasted the following from a previous thread to explain my rationale for what I’m doing;

I am building a device for quickly testing for correct connections on 3 pin XLR microphone cables. It indicates a green LED when the cable is good, a red LED when the cable has any problem, and a yellow LED which latches on a failed test in case the user misses a quick flash of the red LED on an intermittent cable. There is a momentary push button to clear the latched status.

It is not necessary that the type of fault be indicated, “GO”/“NO GO” is enough as no failure will allow it to be used, and the repair tech will be able to see what the problem is when they open it.

I want to be able to test cables up to 100M in length, as might be necessary for testing channels in arena size multicore cables.

It is important to me that the code loop run no slower (be no longer) than is necessary, to minimise the time that an intermittent short can remain present without being detected and indicated.

I have configured three of the pins, the “source” end, as OUTPUT and the three pins on the “receive” end as INPUT. The procedure is to use digitalWrite to set a source pin high, and use digitalRead to see what is received where on the other end.

I have 470R resistors in series with the source output pins to protect them from each other if they are connected together in a shorted cable. Two of them in series between the high pin and the low pin giving 5/(2)470 = 0.005A, or 5mA. I suppose I would get 7mA if I had two low pins connected in parallel giving 470+(470/2).

As the receive end pins are high impedance of around 100MegOhm they are susceptible to floating voltages induced by nearby electromagnetic fields which could result in a receive pin being in a “high” state when it has not been connected to a voltage from a source pin. I have connected 5.1K pulldown resistors to these pins to mitigate this, but I am unsure how I should calculate the optimum value of these to produce an allowable voltage “float” for a given EMI situation.

The negative aspect of these resistors is that they form a voltage divider between the current limiting resistors on the source pins and the pull-down resistors on the receive pins. This reduces the 5V logic high, per Vin * (R2/(R1+R2)). This gives 5 * (5100/5100+470) = 5 * 0.916 = 4.579V. Because the MCU interprets any signal above 3V as “high”, this gives a margin of 1.5V.

There may be up to 10R of resistance per wire in a 100M cable.

Here is the code I am using: Some of the pin numbers have been chosen for reasons of physical assembly, putting all resistors on the same side of the Arduino to make the board narrower, for example.

int LatchClear = 3;
int ScreenReceive = 4;
int HotReceive = 5;
int ColdReceive = 6;
int ScreenSource = 7;                       
int HotSource = 8;
int ColdSource = 9;
int PassLED = 10;
int FailLED = 11;
int LatchFailLED = 12; 
int Score = 0;

void setup() {
  // put your setup code here, to run once:
pinMode(ScreenSource, OUTPUT);
pinMode(HotSource, OUTPUT);
pinMode(ColdSource, OUTPUT);
pinMode(ScreenReceive, INPUT);
pinMode(HotReceive, INPUT);
pinMode(ColdReceive, INPUT);
pinMode(PassLED, OUTPUT);
pinMode(FailLED, OUTPUT);
pinMode(LatchFailLED, OUTPUT);
pinMode(LatchClear, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

 if (digitalRead(LatchClear) == HIGH)
 {
 digitalWrite(LatchFailLED, LOW); 
 } //Polls latch clear switch once per loop and turns off LatchFailLED if switch is pressed during poll. Switch may need to be held for duration of loop.
                                            
 (Score) = 0;                               //Resets score count to zero to begin new test.

 digitalWrite(ScreenSource, HIGH);          //Inject signal onto output XLR pin 1
 if (digitalRead(ScreenReceive) == HIGH && digitalRead(HotReceive) == LOW && digitalRead(ColdReceive) == LOW)    // Check if signal is received on XLR input pin 1 and pin 1 only.
 {
  ++(Score);                                //Increment score count by one if above condition is true
 }
 digitalWrite(ScreenSource, LOW);           //Remove signal from output XLR pin 1
 

  digitalWrite(HotSource, HIGH);          //Inject signal onto output XLR pin 2
 if (digitalRead(HotReceive) == HIGH && digitalRead(ScreenReceive) == LOW && digitalRead(ColdReceive) == LOW)    // Check if signal is received on XLR input pin 2 and pin 2 only.
 {
  ++(Score);               //Increment score count by one if above condition is true
 }
 digitalWrite(HotSource, LOW);           //Remove signal from output XLR pin 2
 

  digitalWrite(ColdSource, HIGH);          //Inject signal onto output XLR pin 3
 if (digitalRead(ColdReceive) == HIGH && digitalRead(ScreenReceive) == LOW && digitalRead(HotReceive) == LOW)    // Check if signal is received on XLR input pin 3 and pin 3 only.
 {
  ++(Score);               //Increment score count by one if above condition is true
 } 
 digitalWrite(ColdSource, LOW);           //Remove signal from output XLR pin 3
 

 if ((Score) == 3)                       //Check if score is 3, which is only possible if all pins have passed.
 { digitalWrite(PassLED, HIGH);          //Turn on Pass LED if test has passed.  
 digitalWrite(FailLED, LOW); } //Turn off Fail LED if test has not failed, necessary to correct results of previous loop if conditions have changed.
 //Latching Fail LED not turned off here, because it is latching.

 else {digitalWrite(FailLED, HIGH); //Turn on Fail LED if test has failed.
 digitalWrite(LatchFailLED, HIGH);//Turn on Latching Fail LED.
 digitalWrite(PassLED, LOW); }      //Turn off Pass LED if test has failed, necessary to correct results of previous loop if conditions have changed.

 


}

I was sceptical about the method of reading the switch but I haven’t had any issues. I suppose it doesn’t particularly matter if it bounces a bit and resets the latch 5 times in a row. I came up with the idea of the incrementing “score” myself, I have no idea if that’s how this sort of thing would normally be done, but it does seem to work. I should probably be using an interrupt for this to get it out of my main code loop, allowing it to loop faster, but I haven’t sat down and understood them sufficiently yet.

Chris

septillion: But if you test long cables as you do I would add some protection. Because when you said you read 5V aka 1023 you probably didn't read 5V and the voltage was probably even higher ;) And it's a bit easier to use pull up then. I would use a 1k pull up and a 100nF cap to GND. And from there a 100k to the pin.

Thank you. I will consider using pullups and writing my outputs low to signify conductivity, if I can understand exactly what "low" does. Could you please explain how you chose a value of 1K for the pullup? Is it this strong to ensure absolute reliability of the voltage in hostile conditions, even if it uses more power when driven low? I explained some of my thoughts about my pulldown values above but I'm not sure how this applies to pullups. Can EMI cause a voltage to float lower?

Is the capacitor for noise filtering or something else? What is the function of the 100k resistor in front of the input which is already 100MEG (per datasheet)?

Chris

Chris935: I had imagined high as being equivalent to connecting the 5V source to the pin through a series resistor representing the pins impedance

Correct! And you can ignore the resistor part, it's very low. Which does not mean you can pull infinite current but even under max load the output will be pretty much 5V.

Chris935: and low as being the absence of the 5V.

Incorrect! Where you tie the output to 5V (the high side) when you set the output HIGH, you tie it to GND (the low side) when you set the output LOW.

And it's floating (absence of both 5V and GND) when it's set as input. And you can pull it to a known side with a pull resistor. It's like a rubber band. Th standard Arduinos have a build in (selectable) pull up resistor which will make the pin HIGH (aka pulled to 5V) as long as nothing makes it LOW.

Chris935: Reading these replies it seems as though writing the pin low essentially connects it to 0V via the pin impedance, (an "active" low rather than a "passive" low) is this correct?

Yep :) You can use a Arduino pin to drive (connect to 5V/HIG) and to sink (connect to 0V/GND/LOW) current. Which state corresponds with active is up to you ;)

Small code tip, don't use seperate names for the pins. Although it's good to know what the are, they are all three just a connection. And for testing it doesn't matter how they are called. And simply using an array ffor the tree pins would reduce the code by 2/3 ;)

Chris935: I have copy and pasted the following from a previous thread to explain my rationale for what I'm doing;

That is not very nice off you. That''s called cross posting and is considered very very rude ;) W put time into helping you and by you scattering all the info all around isn't helping. For that my answer will stop here because the copied text is just to long.

For the ATmega328P, VCC = 5V:

INPUT_PULLUP: Referring to Figure 33-17. ATmega328: I/O Pin Pull-up Resistor Current vs. Input Voltage (VCC = 5V) IOP=140µA. Therefore, R=5/0.00014 = 35.7K

Output HIGH: VOH = 4.48 @ 20mA, see Figure 33-24. I/O Pin Output Voltage vs. Source Current (VCC = 5V) R=(5-4.48)/0.02 = 26Ω

Output LOW: VOL = 0.47 @ 20mA, see Figure 33-22. I/O Pin Output Voltage vs. Sink Current (VCC = 5V) R=0.47/0.02 = 24Ω