Okay - so I'm working on a test fixture for a circuit board we use, and I'm running it with a Nano. Everything was working except that the board under test appears to be drawing some current (a very small amount, but still enough to mess with the tests) through some FETs that are being driven by the Nano outputs when I switch off the main power to the board via a relay. So I thought, "Hey - I'll just switch them to inputs to tristate them while the power is off and then switch them back to inputs when I turn the power back on, to keep that from happening!"
Herein lies the problem: once I switch them to inputs, they don't seem to want to go back to being outputs. I initially set them as OUTPUTS in Setup(). I was using #defines for the pin #'s, and thought maybe that was an issue since the other pinMode statements are in subs. Changed them to int's. No difference. Printed the value it was seeing in the sub to make sure it was seeing the right pin #. It was.
If I set them as outputs in Setup and leave them that way, I can test boards all day, but the second I switch them to inputs and back, they no longer drive the outputs. HELP!?!
The subs in question:
void power_off(void) {
//tristate outputs by making them inputs to see if that fixes voltage leak to CBA
pinMode(DirFET, INPUT);
pinMode(HomeFET, INPUT); // Why does setting them to inputs and then back to outputs later keep them from working??
pinMode(RevFET, INPUT);
//turn off power to motor & logic on CBA
digitalWrite(GroundSwitch, LOW); //power off DUT
}
void power_on(void) {
Serial.println(DirFET);
//restore tristated outputs
pinMode(DirFET, OUTPUT);
pinMode(HomeFET, OUTPUT);
pinMode(RevFET, OUTPUT);
//turn on power to motor & logic on CBA
digitalWrite(GroundSwitch, HIGH);
}
Again, if I remove the pinMode statements from them, the outputs work, but then I have other issues.
Any ideas?
culturedropout:
I was using #defines for the pin #'s
Although this is perfectly fine from a "does it work" perspective, it's better (type safe, more usefull errors etc) if you use const (from constant).
culturedropout:
since the other pinMode statements are in subs functions.
The word you are looking for is function
culturedropout:
Changed them to int's.
Ever planning on using pin -25397? If not, a byte is a better choice. To be more precise:
const byte OutputPin = 5;
culturedropout:
//restore tristated outputs
pinMode(DirFET, OUTPUT);
pinMode(HomeFET, OUTPUT);
pinMode(RevFET, OUTPUT);
Does restore there mode, but it does NOT restore there state And after calling pinMode(pin, INPUT) the output state is set to LOW. So when you then call pinMode(pin, OUTPUT) you have a pin set to output but in state LOW.
culturedropout:
except that the board under test appears to be drawing some current (a very small amount, but still enough to mess with the tests) through some FETs
Sounds like phantom powering to me. But not sure without schematic. Do know it can cause unexpected issues.
Does restore there mode, but it does NOT restore there state And after calling pinMode(pin, INPUT) the output state is set to LOW. So when you then call pinMode(pin, OUTPUT) you have a pin set to output but in state LOW.
The word you're looking for is "their". ;p
I realize that. I call other functions ;D that set the values the way I need them as necessary, so I;m' not assuming their state. I thought I read somewhere that the IDE treats bytes and ints the same in terms of storage space, but I'm probably remembering it wrong.
So any ideas why the outputs stop working when I switch their pinmodes? The pins are just connected to the gates of FETs that open and close one side of the power to the LED in an optical sensor to simulate a flag being present or not. That all works fine as long as I don't mess with the pinMode, and maybe it's impossible to get phantom power through an FET like this, but something is supplying about 2.5V on the sensor's pins when I have the input power to the board turned off with a relay. The LEDs on the board go out, so maybe the voltage I'm reading there is just float, but I got the impression something was keeping the CPU on the board from shutting down and restarting when I cycled the power. Something that doesn't happen if I turn off power to the whole fixture manually. Odd. Well, thanks for the pointers. Old dogs, new tricks, etc.
Sounds like you are assuming pinMode is somehow not working, with no evidence. Put an oscilloscope on the pins, and SEE what's really happening. Otherwise you're wasting everones time. pinMode IS working correctly. It neither knows nor cares what you have connected to the pins. So, something else is going on.
Regards,
Ray L.
some FETs that are being driven by the Nano outputs when I switch off the main power to the board via a relay.
Bad idea to have powered circuits connected to unpowered circuits. Post a circuit diagram.
Schematic attached. The FETs on the right are to turn the LED in the opto sensors off, even if the device under test (DUT) turns them on, to simulate a flag blocking the sensor. The DUT turns the LEDs off when it's not reading the sensors, to save power, as it's installed in very remote locations and has to run on battery power for months at a time. The stepper connection at the top is strictly on the DUT; I just put it there for ease of reference. I didn't include resistors on the FETs because they're only driving LEDs, and the Nano drives the gates high or low when the program is running, so I don't need pull-downs/ups except for the one driving the relay, to keep it from turning on the power before the Nano comes up. Oh - and there is a diode across the relay coil - I just forgot to put it on the schematic.
The Nano turns on the power to the DUT, and checks to see if it's had firmware uploaded by sending a couple of serial commands at 9600bps; if no firmware, it has a boot loader that gives the option to upload firmware via ymodem, so failing to get a response at 9600bps, the Nano switches to 57,600 (the speed required by the boot loader) and checks to see that the bootloader is responding. The Nano reads the firmware from the attached SD card and uploads it to the DUT using a ymodem implementation I wrote. Then it tells the board to boot the firmware and starts issuing test commands to the DUT and reading the results via serial port.
I was never assuming there was anything wrong with the pinMode command; I just thought I was using it wrong - for example maybe I couldn't use it in a function. Since that apparently isn't a problem, I'm guessing that maybe something about tristating them is causing the FETs to latch up or something. As noted, if I just set the pinModes in question to OUTPUT and leave them, it works fine. It's only when I'm setting them to INPUT and then back to OUTPUT that things get weird. And I know the "on" function is being called because I see the pin assigned to DirFET printed on the serial monitor right before I start trying to use them again. I'll keep looking.
-Bill
TF694364081-no frame.pdf (28.5 KB)
You can't leave FET gates floating, as suggested by the schematic. With Arduino you need both a pulldown resistor and a gate current limit resistor, to protect the Arduino output.
Example:
culturedropout:
The word you're looking for is "their". ;p
Sorry, English isn't my first language. But I'm fine with "dan" and "als" Did point out sub vs function because most of the time the term sub is linked with goto. And that's something you really want to leave in the past
byte is a fixed size of 8-bit. int isn't a fixed size variable but is at least 16-bit on Arduino.
But about pinMode(), did you notice this:
septillion:
culturedropout:
//restore tristated outputs
pinMode(DirFET, OUTPUT);
pinMode(HomeFET, OUTPUT);
pinMode(RevFET, OUTPUT);
Does restore there mode, but it does NOT restore there state And after calling pinMode(pin, INPUT) the output state is set to LOW. So when you then call pinMode(pin, OUTPUT) you have a pin set to output but in state LOW.
jremington:
You can't leave FET gates floating, as suggested by the schematic.
I was of the understanding that the current limiting resistor was only needed to prevent high inrush current if the FET was driving a higher load; is that not the case? It's just connecting/disconnecting the LED in an opto sensor.
I understand that a pull-down or pull-up is needed with something like a motor, where you don't want it just taking off until the software initializes, but in this case I didn't think it would hurt anything regardless of how it came up. I only care about the state of the FET once the code is running and driving it.
It was getting pretty crowded on the small piece of breadboard I built this on, so I didn't include the resistors. This is one of the first relatively complicated test fixtures I've built, and I misjudged the amount of space I'd need. Since then, I've laid out a nice big generic test fixture board with room for all the different types of breakout boards I need, voltage regulators, spots for both a Nano, and a MKRZERO depending on how much horsepower I need, and a breadboarding area roughly the size of the board I built this entire first fixture on. Should be sending that to a board house before long. In the meantime, I just need to get the fixture to work as it is.
-Bill
Some are more stressed about gate resistors than others. In my opinion the output of most uC's is rugged enough to charge the gate capacitance of small(ish) mosfets.
As for the driving, the gate of the mosfet needs to me in a known state for a switch. Aka, not floating. If you really don't care about the mosfet state when the uC is still initializing you can leave the pull resistor. But in that light it would not make sense to ever let the gate of a mosfet float (by setting the drive pin to INPUT). So besides pinMode() can also change the "drive state" of a pin next to the "input/output mode", I think you're off a bad start with the overall design if you need to cut power etc. But yeah, without real schematic that's hard to say.
septillion:
Sorry, English isn't my first language. But I'm fine with "dan" and "als" Did point out sub vs function because most of the time the term sub is linked with goto. And that's something you really want to leave in the past
That's okay - you write better in English much better than most people born in the US.
septillion:
byte is a fixed size of 8-bit. int isn't a fixed size variable but is at least 16-bit on Arduino.
But about pinMode(), did you notice this:Does restore there mode, but it does NOT restore there state And after calling pinMode(pin, INPUT) the output state is set to LOW. So when you then call pinMode(pin, OUTPUT) you have a pin set to output but in state LOW.
I'll change those to bytes, in that case. Thanks!
Each of the su... functions... that read the sensors include code to enable and disable the various sensors as needed:
bool testDIR(void) {
oled.clear();
enableSensors();
LogShow(F("DIR Sensor"));
digitalWrite(DirFET, LOW); // close sensor
return CheckFlags(F("101"));
//delay(1000);
}
and "enableSensors" is:
void enableSensors(void)
{
//allow all the sensor LEDs to be operated by the DUT
digitalWrite(RevFET, HIGH);
digitalWrite(HomeFET, HIGH);
digitalWrite(DirFET, HIGH);
}
So I think that should work as expected, right? I'll keep poking...
-Bill
septillion:
Some are more stressed about gate resistors than others. In my opinion the output of most uC's is rugged enough to charge the gate capacitance of small(ish) mosfets.
As for the driving, the gate of the mosfet needs to me in a known state for a switch. Aka, not floating. If you really don't care about the mosfet state when the uC is still initializing you can leave the pull resistor. But in that light it would not make sense to ever let the gate of a mosfet float (by setting the drive pin to INPUT). So besides pinMode() can also change the "drive state" of a pin next to the "input/output mode", I think you're off a bad start with the overall design if you need to cut power etc. But yeah, without real schematic that's hard to say.
You're probably right about not making sense to let the MOSFET float; I wasn't initially planning on needing to tri-state the outputs (and I'm still not sure I do) but the board is getting phantom power from somewhere when I turn off the relay that powers it normally. I'm trying to sort that out. The schematic I attached to a previous message is the real schematic for the test fixture. I can't post the schematic of the board it's talking to because that's proprietary information and I'd be taken out and shot.
The reason I'm switching power off and on is because some of the tests include setting an attached stepper motor to a specific location and then power cycling to make sure the board "remembers" the location, making sure the board's programming survives random power loss, etc. I suppose I could use a bunch of opto-couplers in the design, but how else would you suggest I handle these tasks?
Not taking in consideration the whole mosfet setup, if you do this (assuming blank start aka no calls before) you have:
//DirFET FLOATS
pinMode(DirFET, OUTPUT);
//DirFET is LOW
enableSensors();
//DirFET is HIGH
pinMode(DirFET, INPUT);
//DirFET FLOATS
pinmode(DirFET, OUTPUT);
//DirFET is LOW <<-- Yes, LOW, not the previous HIGH state!
About sorting it out the whole floating business seems more like a patch than a fix. But I missed the schematic, I'll have a look (but I'm running out of time atm).
I was of the understanding that the current limiting resistor was only needed to prevent high inrush current if the FET was driving a higher load; is that not the case?
That is not the case.
The FET gate is a capacitor, and briefly acts as a dead short to ground, every time voltage is applied. So without a current limiting resistor, you are stressing an Arduino output pin with every single ON pulse. Eventually the pin will fail.
If you want your circuits to work reliably, include current limiting resistors or use a MOSFET driver. If you are simply a hobbyist playing around, don't bother.