Sorry, I'm not intending to be a smartass or to give you attitude. Just imploring you to do your due diligence before getting us all excited about a new and mysterious FET phenomenon. And I took your words out of context, a bit. I know you meant that this was not dependent on Arduino libraries.
Personally, for me, it's ALWAYS my code until proven otherwise. I am terrible at coding, and I know it.
No offense taken. I have seen enough to agree with you in principle.
At the risk of again sounding arrogant, i am not terrible at coding. I have been employed for decades to write code that is often safety-of-life critical, as well as code to control heavy industrial machinery (distributed paper machine drive systems, FMS centers, all manner of heavy manufacturing automation). Some of it in days when the words "best" and "practice" did not usually appear one after the other. You had ruled paper and pencil and precious little else. Learned many things in the school of hard knocks.
And I'm not suggesting it's a n00b mistake, or even your mistake, even if it is the code. There are innumerable ways to get unintended bugs. It might be your compiler, errata, erroneous documentation or header files, or a very un-n00b coding error. I can't read your code, but Psi and jwm_ have mentioned some things that have bitten me, repeatedly.
But that is part of my point. The 328P code is absolutely trivial and there is no way in hell it won't do what the source says. If a simple GPIO output was an errata case, the whole product would be unusable for anything. It is guaranteed by experience from numerous earlier cases that the functionality the code exercises does work, and i can see it work by all the tests i care to apply. The output pins switch state exactly when they are supposed to (this has been debugged thoroughly) in both cases.
Try removing R7 when you see the phenomenon. If the MOSFET still conducts after removing the R7, you have a 2N7002-thyristor
Now that is one thing i have not tried yet. I will, but it will be tomorrow as today i am busy with other things.
Have you checked the 12V power supply? Is it noisy? Does it contain fast voltage spikes which could couple capacitively to 2N7002 and keep the 2N7002 in conducting state?
Only superficially. The 12V is nominal only as it is unregulated and varies (it is also clearly higher but that is OK, it has been accounted for). The regulator is a simple LDO so no spiking or ripple appears in the supply, other than the 100 Hz capacitor ripple that is insignificant.
You could also try changing the 10K gate resistor to 1K which would make the gate less sensitive to the capacitive coupling and noise.
Tried it already. No help there.
Pretty weird problem you have in your hands.
You don't say
Before experiencing this i would have laughingly dismissed such problems as just incompetence if someone else had reported it.
But i have now 4 similar circuits on 2 physically separate PCBs driven by 2 different processors (Atmega 328P AVR on the DIY board and a SAM3X ARM on Arduino Due + DIY shield). 3 of those are visible LEDs and the last is the triac opto. All share 1 thing in common and that is the 2N7002 fet and all have the same problem.
Additionally, the above Arduino drives an essentially identical fet circuit on a separate satellite PCB where the fets control internally optoisolated Toshiba SSRs. Those function perfectly and the only difference is that the fet for there is BS170, not 2N7002.
Oh, another test. If you think your atmega (or is it the optocoupler?) isn't pulling close enough to ground, try manually grounding the FET pin through a diode or three to see if that doesn't still turn the LED completely off!
The SAM at least pulls down to ~40mV and if that doesn't turn the fet off then there is no justice. Having said that the fet _does_ turn off if i forcibly ground the gate using a piece of wire. So that would indicate that 40 mV is enough for turn on against everything the data sheet says. At least Fairchild data sheet indicates that not much happens with Vgs below 2 volts. I know from experience that many specimens do conduct between 1 and 2 volts but 40 mV is way below that...