Basic design help Digital pressure regulator

I have a mini pressure regulator 0-30 PSI and a continuous rotation servo motor and UNO , I am using a pressure sensor that outputs 0.5-4.5vdc from 0-30 psi for my feedback.

I have messed with KNOB and SWEEP i9n testing but I am not getting the whole picture set in my brain LOL

So the system is Air into regulator , servo motor screws the knob of the regulator in/out based on Analog voltage in from the pressure sensor on the output of the regulator to close the loop, i will need to calibrate this later .

Here is what I have so far , gotta test now , I found some calibration code Im gonna try out later

_0_5_volt_reg_controller_PID.ino (1.65 KB)

If I understand correctly you want to convert

analogRead of PSI sensor --> voltage --> pressure --> angle to turn a knop

in pseudo code (note I use milli units to keep the math in integer domain)

loop()
{
  
  // adjust knop every 100 milliseconds without delay
  if (millis() - lastAdjust > 100)  
  {
    lastAdjust = millis();

    milliVolt= analogRead(PSIpin) * 5000 /1023;
    milliPSI = map(milliVolt, 500, 4500, 0, 30000);

    angle = map(milliPSI, 0, 30000, 0, 180);  // adjust input range here
    angle = constrain(angle, 0, 180);  // do not get beyond limits.

    analogWrite(angle);
  }
  // do other stuff here
}

The design is a Uno based digital pressure regulator using a standard type air pressure regulator being adjusted by a servo motor and a sensor with analog out as a feedback.
I do not fully understand your code LOL ! not the best at this

thanks for the reply !

I do not have the pressure sensor yet and wanted to test this setup using an external pot to simulate the sensor , I attached the pot to the servo motor shaft as feedback but when I change the PID setpoint it does not do what I expect ? I suspect I have some code wrong.

I think it is where I am sending the PID OUTPUT ? or the format may be wrong ?

CODE notes in RED

//Nanometer technologies Propreitary
//P-I-D pressure regulator

#include <Servo.h>
#include <PID_v1.h>

Servo myservo; // create servo object to control a servo

int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
double Kp=10, Ki=1, Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object

Serial.begin(9600);

//initialize the variables we're linked to
Input = analogRead(potpin);
Setpoint = 1000; should this be in VOLTS or 0-1023 ??

//turn the PID on
myPID.SetMode(AUTOMATIC);

}

void loop() {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 12); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there

Input = analogRead(potpin);
myPID.Compute();
analogWrite(potpin, 9); Should this be Output or 9 ?

// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(voltage);
delay(500);

}

The PID will work in whatever units you like - it has no idea what it is controlling. You just need to ensure that input, output and setpoint are using the same one. PSI seems the obvious one in your case.

So convert the input voltage you read to PSI so the PID can compare it to your setpoint. When it gives you the output value, convert that to a number to feed to servoWrite that will correspond to the desired PSI setting. You don't need analogWrite at all as far as I can see.

wildbill:
The PID will work in whatever units you like - it has no idea what it is controlling. You just need to ensure that input, output and setpoint are using the same one. PSI seems the obvious one in your case.

So convert the input voltage you read to PSI so the PID can compare it to your setpoint. When it gives you the output value, convert that to a number to feed to servoWrite that will correspond to the desired PSI setting. You don't need analogWrite at all as far as I can see.

Input = analogRead(potpin);
myPID.Compute();
analogWrite(potpin, 9);

So make analogwrite servowrite ? to pin 9 or this myservo.write(val);

"When it gives you the output value, convert that to a number"

where is this OUTPUT number in the code ? sorry man not very good at code so I stumble

Look inside the PID_v1 library to see how to use it. It probably has examples too.

MarkT:
Look inside the PID_v1 library to see how to use it. It probably has examples too.

Thats what I am using , using the basic PID from that library

Have you looked inside it? ITs open source, you can read all the code and the documentation alongside it.

MarkT:
Have you looked inside it? ITs open source, you can read all the code and the documentation alongside it.

Sorry I did not mention I am using the PID to make a closed loop system, I used myPID.SetControllerDirection(REVERSE); to reverse the direction , Worked GREAT !