I'm using P-channel mosfets to control the anodes on rows of an RGB LED matrix. Partial schematic attached. N-channel mosfets control the cathodes. It's an 8x32 matrix that works fine when Vdd is 5 volts, but when the voltage is raised to about 8 volts (I need 12 volts to light the LEDS brightly), other rows other than the ones I chose come on. I.E. all rows are on when I just want the top two. I'm using an Atmega328 and 74LS138 decoder to select one of the 8 rows.
So, to reiterate: if voltage is <8 volts, the rows I want to light, work. If >8 volts, the same rows light up but then so do all the rest in the same columns. I know it has something to do with the Vgs but my attempts to pull the voltage down to 5 volts with NPN transistor with/without zener diode, have failed. The mosfets are FQU11P06, Vgs between 2 and 4 volts. I think some calculations may be in order.
The gate to source resistor is 10k ohms
This is my first time using mosfets...I'm a small-signal BJT guy.
By way of the gate pullup resistors like R4, you are applying 8V or 12V to the output of the LS138. And it's probably the case that current is flowing back through that output to the 5V rail, or perhaps even to ground. That current flow drops the gate voltage and the mosfet turns on.
Microprocessor GPIO port pins have protection diodes from ground to the pin, and from the pin to Vcc. I believe 74HC and 74HCT outputs do as well. But so far as I know, 74LS outputs do not have those diodes. But they do have bipolar transistors, and when an output is off (high), a transistor from Vcc to the pin is turned on, and it appears to be possible that a high enough voltage would cause current to flow backward through that transistor.
If that's the problem, one solution would be to add an NPN transistor for each P-channel mosfet, and drive the NPN's base through a resistor. When turned on, the NPN would ground the mosfet's gate, turning it on. But you would need to use a 3-to-8 decoder with active high outputs. I think the 74LS238 (or 74HC238) would do that.
MOSFETs are neat and conceptually are relatively simple. You need to place a voltage on the gate (always reference the source) that is for the gate a negative for P-channel and positive for N-channel referencing the source. Source P-channel or Positive N-channel for negative. The Vgs is a minimum voltage to turn it on. The data sheets shows that and the RDSon (Resistance Drain Source when on). If the source is connected to +5 and the gate is grounded and Vgs is exceeded it turns on. Note the reference +5. The gate is grounded so from +5 that is -5 as far as the MOSFET is concerned. I try to keep my gate resistors below 50 Ohms so I get a relative clean switching from the MOSFET. The resistor in series causes it turn on and off slowly causing unnecessary heating and sometimes other weird things. It is a good design practice to add pull resistors on the output of any device that is undefined or set as an input during reset such as the Arduino. An important rule is never feed voltage into an output unless it is designed for that, they will typically have open drain or open collectors (it is possible with tristate parts). Try searching for "octal high side LED driver" there is a diverse variety of chips that basically incorporate your circuit.
I would suggest MIC5891 to source current to the anodes. So much less wiring to do, and it's a shift register so you can daisy chain 4 of them to have 32 sources controlled by 3 pins.
Mouser has them in stock https://www.mouser.com/Search/Refine?Keyword=mic5891
If you want to switch on the high side with a p-channel MOSFET then unless the supply
is the same as the Arduino Vcc you must use a level shifting circuit to drive the gate of
the p-FET.
8V on a logic chip will damage it - never let that happen...
I think you need a simple NPN level shifter to drive non-logic-level p-FETs if you use
a discrete circuit for the anode drivers. The one-chip solution is probably simpler, does
it all in one.
Thank y'all...will analyze and get this thing fixed. I was going to post some photos and schematics of what I'm doing but "replies" don't allow for attachments. I'm way, way, committed at this point so I have to find a solution that does not involve making a new logic board.
I think this circuit would work. Instead of an NPN, you would use a little TO92 N-channel mosfet, the 2N7000, or perhaps a BS170, added to each P-channel mosfet. When the 138 output goes low, Vgs of the N-channel would increase to 5V and it would turn on, which grounds the P-channel gate, which turns it on. And the 74LS138 is replaced by a 74HC138, which has a high output very close to the 5V rail. The LS might work, but the HC will be more reliable, and the pinout should be the same. No additional resistors are required.
By connecting the HC138 output to the N-channel's source, you preserve the original active-low logic level of the 138.
NEW info: I decided to get more analytical instead of just hacking and found something unusual that I think is causing my problems.
Because I'm not that good at software (unless it's Assembler) I decided to make my circuit so it would be compatible with Adafruit's RGBPanelMatrix library (and their 16x32 LED matrix). What I display on the Adafruit display panel, I want to display on my own MUCH bigger display.
I was wondering why my 74138 o/ps were all high and found the address inputs connected to A0,A1, and A2 have a bias to them of 2.0 volts! With a blank MPU, these pins are at 0 volts (maybe because on boot they are inputs?). In any case, with the program loaded, the o/p is 2.0 volts.
So...I suspect it's in the library and how those pins are defined that is giving me the bias, and when I apply my 12 volts, it just gives enough voltage on the gate of the mosfet to turn it on. At 4.11 volts (5 volt input) lights are off, at 4.31 volts on the gate (12v input), all lights are on. So my Vgs turnon is little bit more than 4.11 volts. Can someone look at the Adafruit library and tell me why A0,A1,A2 of the Atmega 328 are at 2.0 volts at "idle"??
Thanks for the tip about reviewing and ability to add attachments as I have no done. Photo was an early test of my boards. Matrix is 5 feet across with 8 boards holding pixel LEDs and the Row and Column Mosfets. The little board at top (in photo) is the logic board with 328 MPU and 74HC138. A 2x4 IDC ribbon cable connects the o/ps of the '138 to the P-channel Fets.
Thanks ShermanP for the circuit...already tried that...didn't work, but then this may not be the problem!
Here's the relevant code I'm using from Adafruit examples. Here I'm only lighting up 2 rows, and 2 columns, for testing purposes.
#define CLK 8 // USE THIS ON ARDUINO UNO, ADAFRUIT METRO M0, etc.
//#define CLK A4 // USE THIS ON METRO M4 (not M0)
//#define CLK 11 // USE THIS ON ARDUINO MEGA
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
void setup() {
matrix.begin();
uint8_t r = 0, g = 0, b = 0;
// Draw top half
for (uint8_t x = 30; x < 32; x++) { //columns 0-31
for (uint8_t y = 0; y < 2; y++) { //rows 0-7
I'm not sure what you mean by "bias". If that's the voltage reading on the pins, it may just be the average voltage where each line is being multiplexed on and off rapidly. Perhaps you could write a simple test sketch, not using the library, that brings one of the three address lines high while the other two are brought low. That will select one of the eight outputs as low while the other seven are high. And set the other 328P outputs to whatever you need to get one segment to light up. You can put all that in setup(), and leave loop() empty. Then you can measure the voltages on the three lines and the HC138 pins, and see if they are what you expect them to be. You can also see what happens at 8V and at 12V.
I think you said before that this all works when the 12V line on the schematic is actually set to 5V. If that's the case, then I think it's unlikely that the library is doing anything wrong.