For a constant current drain using a PWM input I am using the following setup:
simulate this circuit – Schematic created using CircuitLab
For small currents it seems to work as expected - the op-amp producing a voltage to the MOSFET which causes the current flow over the battery be such that the voltage drop over the 3.3 Ohm sense resistor becomes exactly the configured voltage, as expected.
But there must be something I have missed, because the current I can get maxes out much earlier than expected. This happens around 150 mA corresponding to an input voltage to the op-amps positive input (via PWM) of around 0.45V. At this point, the output from the opamp to the MOSFET seems to saturate around 6.05V. The problem is that further increases in the op-amps positive input has no effect. The opamp keeps producing a 6.05V output even though there is a large difference between the positive and negative input. I can see the opamp is getting, say, 0.8V at the positive input and is only seeing 0.45V at the negative input, yet it refuses to output more than 6.05-6.1V.
The Vcc to the op-amp is 12V so there should be plenty of headroom for it to output higher voltages even though it isnt a rail-to-rail opamp. I have looked in the datasheet but I cant seem to find a limitation that would explain this behavior, so I hope someone can explain what I am missing.
Update! I am a bit closer to resolving the mystery. I had a wire (not on the drawing) going from the output of the op-amp and to an analog input on the Arduino. I thought the analog inputs were high impedance so it wouldnt affect anything. But with that wire there I am seeing the 6V saturation (as measured by a multimeter, the Arduino only measures to 5V), but if I disconnect it everything works. Is this some type of oscillation involving the Arduino? Or is the Arduino draining the voltage?
NOTE! The root cause of this problem turned out to be different. I had connected a measuring wire from the op-amp output to the Arduinos analog input. My thinking was that it was high impedance and hence wouldnt affect outcome. I had noticed the measurements topping out after 5V but thought that was simply due to it being unable to report more than value 1023 and that it wouldnt actually affect the behavior of the circuit. This assumption was wrong; due to a protection diode in the Arduino inputs, the extra voltage was drained (the LM358P has a short-circuit voltage of 40-50 mA) causing the drop in the measured voltage (even with a multimeter) at the op-amp output. But the real culprit was the protection diode in the Arduino. Removing this measurement wire resolved the problem. I am leaving the original problem description in place so other people can find this report in case they encounter similar issues.