PWM current sense adjustment

Hi all,

Ok, a few of you will have read previous threads based around this concept by myself. However after trying alternative methods with no joy I'd like to see a few different suggestions on achieving the goal.

Basically, I have the attached circuit rigged up on a breadboard. This circuit uses a POT mapped to PWM output to control the gate of a low side NMOS which in turn controls the current to a proportional solenoid coil on a proportional hydraulic relief valve. I am using a 0.08R resistor and INA193 to give an analog input through a low pass filter to the Arduino input A5, thus giving me current feedback between 0-5v for a 0-3amp load. The feedback works well between these values and control of the proportional solenoid coil works exactly how I wish.

My primary problem:

As the coil heats up over prolonged use, the resistance increases and therefore the current decreases (ohms law). The knock on effect of this is that the pressure of the proportional relief valve decreases over time regardless of what the POT (duty cycle) is set at.

My strategy:

Using a calculated 0.08R resistor and INA193 current shunt amplifier I've been able to monitor the actual current drawn through the ADC on the Arduino. As the coil draws between 0 and 3A, I have been able to translate this to between 0-5V correspondingly using the above hardware and an analog input pin on the arduino.

My goal:

Using the input from the INA193 (analog pin A5) I would like to monitor the actual current being drawn and increase / decrease the duty cycle as the current decreases / rises. This wouldn't be to much of an issue if the duty cycle was a constant. However as the duty cycle is controlled via a POT (analog input A0), it is subject to change depending on the pressure the user requires. Once set the POT may not be adjusted for another 3 hours, or it maybe tweaked after just a few seconds or minutes. Either way, as the coil temperature increases, the resistance increases, the current drops and ultimately the pressure reduces itself regardless of the POT setting.

My question:

What is the best method of controlling the duty cycle via programming to mainly increase or decrease as and when the actual current begins to drop? I need some form of reference or link between POT value and PWM duty cycle.

A previously tried method was to monitor the POT. Every time it was adjusted, wait 3 seconds (allow current to stabilise) and then read the ADC input (A5) from the INA193 to give me the current at that time. Then as the current reduced over time adjust the PWM duty cycle so that the actual current matches the saved current taken 3 seconds after initial POT adjustment. Unfortunatly this didnt work as well as hoped due to the speed in which the POT could be adjusted and the amount of adjustment.

Others have suggested a lookup table from POT reading to required output of PWM duty. If there is fluctuations adjust PWM as needed.

Either way, I am open to suggestions on howto achieve this. There must be a more straight forward and reliable way to work this.

The code below is my basic operation code. However I need to implement the above solution into this code:

const int analogInPin = A0;   // Analog input pin that the potentiometer is attached to
const int analogOutPin = 3;   // PWM Output to coil
const int senseR1 = A5;       // Current sense 

int outputValue = 0;        // value output to the PWM (analog out)
int bits = 0;
int cSense1 = 0;

const int numReadings = 20;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  //Pin 3 - 122 Hz PWM / dither frequency
  //TCCR2B = (TCCR2B & 0b11111000) | 0x06;
  
  //Pin 3 - 245 Hz PWM
  //TCCR2B = (TCCR2B & 0b11111000) | 0x05;
  
  //Pin 3 - 30 Hz PWM
  //TCCR2B = (TCCR2B & 0b11111000) | 0x07;

  //Average out current senseR1
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;}
}

void loop() {
  
  // Map POT to PWM Duty
  sensorValue = analogRead(analogInPin);
  outputValue = sensorValue / 4.011;
  analogWrite(analogOutPin, outputValue);

  // Calculate adverage of current sense (INA193)
  total = total - readings[readIndex];
  readings[readIndex] = analogRead(senseR1);
  total = total + readings[readIndex];
  readIndex = readIndex + 1;

  if (readIndex >= numReadings) {
    readIndex = 0; }
  bits = total / numReadings;
  delay(1); 

  // print the results to the serial monitor:
  Serial.print("sensor = " );                      
  Serial.print(sensorValue);      
  Serial.print("\t output = ");      
  Serial.print(outputValue);
  Serial.print("\t rSense = ");
  Serial.print(bits);
  Serial.println(" bits ");
  
           
}

I look forward to any feedback.

Many thanks,

Circuit Diagram Update.JPG

I don't see your problem. You can make the output conform to some scaled value of the pot setting, adding a negative feedback value from the current sense. Why is this complicated?

...and it's a duplicate post. It's not fair to deprive readers of the replies that have already been given to this. POT movement as Event trigger to execute millis() - Project Guidance - Arduino Forum

If you still don't want to use a PID controller, as suggested in the original thread, what other answers do you expect?

The code above implements a P controller, with all known problems of that model. You need at least a PI controller for your problem.

Your code also is buggy, in calculating total you only replace the previously measured value by the current one.

Hi, Jim

I'm a bit confused how your averaging calculation works, I thought this might be easier.

float  averagecurrent = 0;
  for (int i = 0; i < 20; i = i + 1)
  {
    averagecurrent = averagecurrent + float (analogRead(senseR1));
  }
  averagecurrent = averagecurrent / 20.0;

With your reasoning on how to control your current , you will have to realize your pot will not be setting PWM, it will be setting the required current.

The basic simple feedback procedure would be something like this.

  • When you start the sketch, you set PWM to 0.
  • Read the POT, this is your SET POINT, say you set it to 2Amps.
  • Read the FEEDBACK CURRENT input (average).
  • Compare it to the SET POINT.
  • If the FEEDBACK is LOWER than the SETPOINT, INCREASE the PWM by say 1%.
  • If the FEEDBACK is HIGHER than the SETPOINT, DECREASE the PWM by say 1%.
  • LOOP BACK to 2.

This is just a basic crude explanation of what you are looking for.
The POT sets the CURRENT and the code ADJUSTS the PWM to get the FEEDBACK value to equal the POT setting.
Improvements would be that if the FEEDBACK current is within 5% of the SETPOINT, then no INCREASE or DECREASE occurs.
You may have to increase and decrease by more then 1% steps.
As suggested earlier, PID control would be the prefered way to get fine and quick response to load changes.

Tom... :slight_smile:

Your suggestion has already been discussed, and the increment and delay was found quite unusable. See the preceding thread mentioned above.

Ok thanks all.

Thought it might be easier for the readers if I started a fresh thread with all the information to discuss alternative methods.

I will continue as I'm doing.
Thanks

Have a part#, link or datasheet for your valve? Many proportional valves are 24V ... but yours is 12V?