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,