N-channel FET to convert voltages

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...

Perhaps try a stronger pullup - 10k might be a bit slow, and a slowly changing logic line voltage is going
to cause timing spread. These logic chips are designed for nano-second scale risetimes.

The 25pF output capacitance of the 2N7000 together with the 10k pullup give a time-constant of 250ns,
whereas something like 5ns is expected from a logic line. Try a 470 ohm pullup for 12ns risetime.

I miss two things.

  1. a schematic of how it is all wired. Without that, no way to judge your circuit. Did you remember the decoupling caps for the '595s?
  2. your code pulsing the latch pin.

MarkT:
Perhaps try a stronger pullup - 10k might be a bit slow, and a slowly changing logic line voltage is going
to cause timing spread. These logic chips are designed for nano-second scale risetimes.

The 25pF output capacitance of the 2N7000 together with the 10k pullup give a time-constant of 250ns,
whereas something like 5ns is expected from a logic line. Try a 470 ohm pullup for 12ns risetime.

Thank you, that fixed my issue.

wvmarle:
I miss two things.

  1. a schematic of how it is all wired. Without that, no way to judge your circuit. Did you remember the decoupling caps for the '595s?
  2. your code pulsing the latch pin.

RCLK is the 595's latch pin - it's tied to the clock.