I am trying to use an N-channel FET (2N7000) to control a shift register (SN74HC595).
I have connected the FET like this:
- MCU pin "P_CLK" - 470Ω - gate - 10kΩ - GND
- source - GND
- SRCLK and RCLK - drain - 10kΩ - 3V3
Tying SRCLK and RCLK together will cause the SR outputs to be 1 clock cycle behind the SR memory (datasheet 7.6).
SER and SRCLR are connected directly to the MCU.
OE is pulled LOW.
I am using 3.3V for everything to test; the SR will run at a higher voltage later on.
Here is my code:
#define P_DAT D1 // directly to SER
#define P_CLK D8 // via FET to SRCLK and RCLK
#define P_CLR D2 // directly to SRCLR
void setup(){
digitalWrite(P_CLK, 1); pinMode(P_CLK, OUTPUT); // SRCLK rising-edge trigger; FET inverts output and defaults to 1 when P_CLK floating
digitalWrite(P_CLR, 1); pinMode(P_CLR, OUTPUT); // SRCLR active-low
digitalWrite(P_DAT, 0); pinMode(P_DAT, OUTPUT);
Serial.begin(115200); Serial.println("");
/* control SR via FET */
digitalWrite(P_CLR, 0); digitalWrite(P_CLR, 1); // SR mem = 00000000
digitalWrite(P_CLK, 0); delayMicroseconds(1); digitalWrite(P_CLK, 1); // SR out = 00000000; DAT=0, so SR mem remains 00000000
Serial.println("SR mem = 00000000; SR out = 00000000"); delay(10000);
digitalWrite(P_DAT, 1);
digitalWrite(P_CLK, 0); delayMicroseconds(1); digitalWrite(P_CLK, 1); // SR mem = 00000001; SR out = 00000000
Serial.println("SR mem = 00000001; SR out = 00000000"); delay(10000);
digitalWrite(P_DAT, 0);
digitalWrite(P_CLK, 0); delayMicroseconds(1); digitalWrite(P_CLK, 1); // SR mem = 00000010; SR out = 00000001
Serial.println("SR mem = 00000010; SR out = 00000001"); delay(10000);
/* control SR directly */
Serial.println("disconnect FET. connect P_CLK directly to SR"); delay(15000);
digitalWrite(P_CLK, 0);
digitalWrite(P_CLR, 0); digitalWrite(P_CLR, 1); // SR mem = 00000000
digitalWrite(P_CLK, 1); digitalWrite(P_CLK, 0); // SR out = 00000000; DAT=0, so SR mem remains 00000000
Serial.println("SR mem = 00000000; SR out = 00000000"); delay(10000);
digitalWrite(P_DAT, 1);
digitalWrite(P_CLK, 1); digitalWrite(P_CLK, 0); // SR mem = 00000001; SR out = 00000000
Serial.println("SR mem = 00000001; SR out = 00000000"); delay(10000);
digitalWrite(P_DAT, 0);
digitalWrite(P_CLK, 1); digitalWrite(P_CLK, 0); // SR mem = 00000010; SR out = 00000001
Serial.println("SR mem = 00000010; SR out = 00000001");
}
void loop(){
}
I'm testing the SR outputs with a yellow LED connected through 1kΩ.
What should happen with each SRCLK/RCLK pulse is this:
- SR cleared. Memory and outputs set to 00000000. LED is off.
- SR reads a 1 into memory. Memory becomes 00000001. Outputs unchanged. LED still off.
- SR reads a 0 into memory. Memory becomes 00000010. Outputs become 00000001. LED turns on.
What actually happens using the FET is that the SR outputs become 00000001 in step 2, as if SRCLK/RCLK are triggered twice. Outputs are still 00000001 after step 3, as if SRCLK/RCLK are not triggered at all.
If I bypass the FET and connect the "P_CLK" pin directly to SRCLK and RCLK, running the same code (aside from not inverting "P_CLK"), everything works as expected. The LED turns on in step 2 and off in 3.
Something is going wrong with my 2N7000 setup, but I have no clue what...