Go Down

Topic: [SOLVED} MOSFET continuously conducts (Read 8014 times) previous topic - next topic

dwightthinker

I'd think that if there is a capacitive coupling to the gate, one could get
a relaxation oscillation started.
It might slow the response of the opamp enough to oscillate.
I think it might depend on leakage from the source or drain to the gate.
Tinker Dwight

raschemmel

Quote
I'd think that if there is a capacitive coupling to the gate, one could get
a relaxation oscillation started.
It might slow the response of the opamp enough to oscillate.
I think it might depend on leakage from the source or drain to the gate.
Tinker Dwight
I removed the cap (10 nF) from the gate to the analog feedback line and left the cap from the output of the op amp to the feedback line as well as the resistor (which the OP removed).

I'll have more information tonight when I scope it out.

BTW, maybe nobody noticed but if you right click on the photo of the meter and select "Open image in new tab " you'll see the P.S. used to power the op amp is set to 8.5 V instead of 12V or 10.5 V. This is because I noticed that the voltage across the resistor actually INCREASED when I lowered the op amp power voltage from 10V to 8.5 V. It went from 4.88 V to 4.96 V.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

dwightthinker

Lowering the supply voltage most likely effected the offset of the opamps.
These are not quite instrument quality ICs. One typically adds a trim resistor
for offset.
Dwight

raschemmel

I scoped it out and there was no oscillation to compare to the PWM.
Here is a video of the circuit regulating at 650 mA
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

dwightthinker

I'm curious about the PWM. Why is it jumping around?
I thought it was suppose to just be part of 256 of a cycle.
Could you also measure the opamp output voltage when you have it set
for some known current?
Dwight

raschemmel

#80
Oct 04, 2016, 05:06 am Last Edit: Oct 05, 2016, 02:43 am by raschemmel
Look at the code.
You can see from the meter reading and ths terminal capture file that it is regulating .
How it does that has to be based on the code. It's all there in the post with the photos.

Quote
Could you also measure the opamp output voltage when you have it set
for some known current?
Op amp output voltage is rock solid at 3.80 V +/-20 mV for a current setpoint of 650 mA (0.650 A)
The current sense resistor voltage is 1.333 V +/- 20 mV for that same setpoint. The voltage on the gate is the same as the op amp output. The votlage across the 1 k resistor is 0.003 V (3 mV) which as you know means the mosfet gate is drawing 3 uA (because mosfets are voltage controlled not current controlled). The only conclusion anyone can draw based on all the observations presented in Reply #66 is that the PWM is fluctuating rapidly because that is how it keeps the current stable. This is similar to how the F22 Raptor air control surfaces work under computer control. That aircraft is not aerodynamically stable so the air control surfaces have to adjust thousands of time a second, meaning such an airframe design could never fly using the old direct mechanical link between the pilot controls and the air control surfaces. The computer keeps it stable by rapidly adjusting much faster than humanly possible. If you look at the voltage on the current sense resistor and look at the serial print terminal capture for the 650 mA setpoint you see that it is indeed compensating rapidly:
I will say that the resolution of the regulation (accuracy) leaves something to be desired.
The attached plot shows it is regulating the current to 650 mA +20/-40 (from 641 to 670 mA)
I would not be at all surprised if you told me that it was because my code was primitive. I'm not a programmer so I just threw something together . If you can do better then you are more than welcome to post some different code for me to try.


Quote
0.6500489
0.6353861
0.6256110
0.6085044
0.6451613
0.6451613
0.6085044
0.6085044
0.6427175
0.6451613
0.6256110
0.6133920
0.6353861
0.6500489
0 0.6256110
0.6231672
0.6231672
0.6451613
0.6256110
0.6256110
0.6231672
0.6353861
0.6256110
0.6085044
0.6329423
0.6549365
0.6256110
0.6451613
0.6451613
0.6085044
0.6256110
0.6231672
0.6549365
0.6133920
0.6133920
0.6451613
0.6353861
0.6133920
0.6500489
0.6549365
0.6256110
0.6280548
0.6549365
0.6500489
0.6329423
0.6500489
0.6304986
0.6280548
0.6549365
0.6451613
0.6329423
0.6647117
0.6353861
0.6598241
0.6695992
0.6280548
0.6280548
0.6647117
0.6647117
0.6329423
0.6622679
0.664711



THIS IS what it looks like when I comment out the serial prints to obtain maximum feedback loop speed.
Note the voltage on current sense resistor is more stable (hence the current is probably more accurate but unfortunately I can't capture the current measurements without serial prints. (catch-22)
Judging from the fact that the current sense resistor voltage is much more stable, I would conclude that the inaccuracy (+/- 40 mA deviation)  shown in the plot was caused by the feedback loop slowed down by the serial prints, causing overshoot during serial prints , requiring more compensation and more overshoot etc. Once the serial prints were removed, the feedback loop was able to operate at full speed resulting in a more stable voltage on the current sense resistor.

Compare the stability of the current sense resistor voltage shown on the meter in the above video to the fluctuation in the meter readings in the original video here.



Here's the new code:
Code: [Select]
int pwm_pin = 3;
int pwm_cmd = 108;
int voltage_cnts;
float voltage;
float current;

void setup()
{
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(pwm_pin,OUTPUT);

}

void loop()

{
  // put your main code here, to run repeatedly:
  
voltage_cnts = analogRead(A0);
voltage = voltage_cnts * 0.004887585532746823069403714565;
current = voltage/2;
 // Serial.println(current,7);
 // delay(1);

analogWrite(pwm_pin, pwm_cmd);

 
  
}  



Here's the photo of the PWM .

Ch-1: Amp/Div = 1V/div
Ch-2: Amp/Div = 2V/div

Time/Div =  0.5 mS

C = 108: (2.137 V)
R = 2.125 ohms
I = C/R = 1.005 A

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Jiggy-Ninja

#81
Oct 04, 2016, 03:04 pm Last Edit: Oct 04, 2016, 03:05 pm by Jiggy-Ninja
You don't need to do active feedback corrections in code like that, that's what the op amp is for. It already has a feedback connection from the resistor that it uses to keep the current stable at the right value. The most you should have to do is infrequent calibration to factor out any circuit bias, tolerance errors and the temp co of the resistor if you need. Once that's done, you just put the calibration-adjusted setpoint into the control input and let the amp's feedback loop take care of the rest.

I guarantee that pretty much any op amp you pick is going to have a much better control bandwidth than a 10 ksps ADC. Diddling around trying to make another feedback loop around the one that already exists, and using inadequate parts, is going to have worse performance no matter how good your coding is.

I think you're being fooled by the scope. Analog scopes are really bad at showing uncorrelated noise, which is what your loops oscillations would be when reading the resistor voltage. Slowing the control loop down would probably help it. The circuit has a severe bandwidth limitation with the LPF on the input. If you're using the same values as the OP, it's roll off was 3 or 5 Hz, I think I calculated. The control loop will easily run at least 1,000x faster than that. Couple that with the fact that your set point calculation is basically all I and no P-D, you're going to have a huge problem with integral windup when you run it too fast.

The only purpose of the connection to the ADC is to detect when the regulator is running out of regulation, either because of a circuit fault or if the load is too weak to provide enough current. And in those cases, the controller won't be able to do anything to correct the situation, the most it can do it display a fault indicator and/or shut the circuit off to prevent unsafe operation.
Hackaday: https://hackaday.io/MarkRD
Advanced C++ Techniques: https://forum.arduino.cc/index.php?topic=493075.0

raschemmel

#82
Oct 04, 2016, 03:53 pm Last Edit: Oct 05, 2016, 04:25 pm by raschemmel
I got rid of the active control and it works. The pwm is stable and the current sense resistor voltage is stable . Will post photos after work today.

V=8.5V

V/2 =4.25V

pwm_cmd =216

5V/254= 0.01968503937007874015748031496063 V

216* 0.01968503937007874015748031496063V = 4.25 V








1- I admit I sort of missed the boat by forgetting the op amp was the control element and not the code.

2- The scope is accurate despite the fact that it is old. Everything we have seen can be explained by the code. Your original comment that the ramp wave has nothing to do with the PWM was correct when you didn't know I was doing unnecessary software correction with the IF statements. After removing that code the ramp wave  (that everyone is calling "oscillation" when it is not) is gone. I think you have been using better scopes for so long you no longer trust the old ones which still work well within their limits. My scope is fine.

3- The circuit is stable once I removed the If statements. The current sense resistor voltage is rock solid, unlike the first video where it was jumping around. After removing the serial prints the voltage was much more stable but the pwm was still rapidly changing until I removed the IF statements.

4- I'm using Linear LT1215s and it is an excellent op amp.

5- What we were seeing before was not oscillation per se but the code incrementing and decrementing the pwm command and then overshooting because the serial print is tying up the processor.

6- The pwm is so stable now that I don't need a video. It would be pointless. A photo will suffice.


C = 216: (4.2519 V)

R = 2.2058   ohms

I = C/R = 4.2519 V/2.2058  ohms =1.927528 A

Here's the code with C =V/2 (| where V = 8.5 V, R = 2.2058 ohms)

Code: [Select]
int pwm_pin = 3;
int pwm_cmd = 216; //((8.5/2)/(5/254)
int voltage_cnts;
float voltage;
float current;

void setup()
{
  // put your setup code here, to run once:
Serial.begin(115200);
pinMode(pwm_pin,OUTPUT);

}

void loop()

{
  // put your main code here, to run repeatedly:
  
voltage_cnts = analogRead(A0);
voltage = voltage_cnts * 0.004887585532746823069403714565;
current = voltage/2;
 Serial.println(current,7);
 // delay(1);

  
analogWrite(pwm_pin,pwm_cmd);

}


Here's the photo of the PWM





Ch-1: Amp/Div = 2V/div
Ch-2: Amp/Div = 2V/div

Time/Div =  0.5 mS

Note: resistance of R obtained from bench power supply set to 6.0 V
                        Current displayed : 2.72 A => R = V/I = 6.0/2.72 = 2.2058
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

raschemmel

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Go Up