So I am basically trying to have the Arduino to run a flow controller HFC-302 specially calibrated for Nitrogen/Air. They specially requires a bipolar +15V, -15V and COM to run [don’t worry about the gas for now]. Now based on the connection document available online for the reference, pin 05 and pin 12 which are also internally connected in the flow controller are signal common , and hence the pins 05 in my case has been connected to the COM of the power supply. To ensure proper grounding, pin 07 on the controller was earthed on the GND case of the power supply and the Arduino GND was connected to the board of the breadboard on row 15. Similarly, the Resistor and capacitor was also connected, as the input from the Arduino was considered using the PWM 5 and hence has to be converted to the analog signal, the resistor and capacitor used are respectively 10kohms and 10uF for the conversion. Now when I will use the code , the signal will move from PWM to then via RC circuit to the controller and output will be obtained at pin A1 of the Arduino taking output from the flow controller from pin 06. The issue is that I am observing -0.4V between PWM and pin 05 on the flow controller with no flow condition. Maybe the grounding is not proper, but I am not sure if this is normal, anyone has any recommendations. for connecting the wires I am using WAGO221 connectors .
They often say that a picture is worth a thousand words. Please make a drawing. Clearly show the connections between all components; don't forget GND and power lines.
Please post a (link to) the datasheet / user manual of the HFC-302.
Thank you so much for reply, given below I have uploaded the manual and the connection drawing , apologizes for I am not good in drawing, if you have questions let me know, I will be adding the code as well.
/ ---------------- USER CONFIG ----------------
const int pwmPin = 5; // PWM output to flow controller
const int analogPin = A1; // Analog input from flow controller const float fullScaleVoltage = 5.0; // Maximum voltage representing full flow const float fullScaleFlow_H2 = 1000.0; // Hydrogen full scale flow in sccm const float H2_correctionFactor = 1.41; // Gas correction factor if MFC is calibrated for another gas float zeroOffset = 0.0; // Voltage reading when flow is zero float calibrationOffset = 0.0; // Optional voltage calibration if measured voltage is slightly off // ---------------- CONTROL PARAMETERS ----------------
/ ---------------- USER CONFIG ----------------
const int pwmPin = 5; // PWM output to flow controller
const int analogPin = A1; // Analog input from flow controller
const float fullScaleVoltage = 5.0; // Maximum voltage representing full flow
const float fullScaleFlow_H2 = 1000.0; // Hydrogen full scale flow in sccm
const float H2_correctionFactor = 1.41; // Gas correction factor if MFC is calibrated for another gas
float zeroOffset = 0.0; // Voltage reading when flow is zero
float calibrationOffset = 0.0; // Optional voltage calibration if measured voltage is slightly off
// ---------------- CONTROL PARAMETERS ----------------
float Kp = 2.0; // Proportional gain for PWM adjustment
int pwmValue = 0; // Stores current PWM value
float desiredFlowPercent = 0; // User input desired flow %
unsigned long startTime; // Timer for logging time
bool simulationRunning = true; // Flag to control STOP/START
void setup() {
// Initialize serial communication at 9600 baud
Serial.begin(9600);
// Set PWM pin as output
pinMode(pwmPin, OUTPUT);
// Print CSV header for easy plotting
Serial.println("Time_ms,PWM_Voltage,Measured_Voltage,Error_Voltage");
// Initialize timer
startTime = millis();
// Instructions for user
Serial.println("Enter desired flow % (0-100) via Serial Monitor:");
Serial.println("Type STOP to pause simulation and START to resume.");
}
void loop() {
// ---------------- HANDLE USER INPUT ----------------
if (Serial.available() > 0) {
String inputString = Serial.readStringUntil('\n'); // Read input until Enter
inputString.trim(); // Remove any whitespace/newline
if (inputString.equalsIgnoreCase("STOP")) {
// Pause the simulation
simulationRunning = false;
Serial.println("Simulation stopped. Type START to resume.");
}
else if (inputString.equalsIgnoreCase("START")) {
// Resume simulation
simulationRunning = true;
startTime = millis(); // Reset timer for logging if needed
Serial.println("Simulation resumed.");
}
else {
// Treat input as desired flow %
desiredFlowPercent = inputString.toFloat();
desiredFlowPercent = constrain(desiredFlowPercent, 0, 100); // Limit between 0-100%
}
}
// ---------------- CLOSED-LOOP CONTROL ----------------
if (simulationRunning) {
// Convert desired flow % to desired voltage
float desiredVoltage = (desiredFlowPercent / 100.0) * fullScaleVoltage;
// Read measured voltage from MFC (0-1023) and convert to 0-5V
float measuredVoltage = analogRead(analogPin) * (5.0 / 1023.0);
measuredVoltage = constrain(measuredVoltage, 0.0, fullScaleVoltage);
// Apply zero offset and calibration offset
float correctedVoltage = measuredVoltage - zeroOffset + calibrationOffset;
correctedVoltage = constrain(correctedVoltage, 0.0, fullScaleVoltage);
// Calculate error voltage
float errorVoltage = desiredVoltage - correctedVoltage;
// Update PWM proportionally to reduce error
pwmValue += Kp * (errorVoltage / fullScaleVoltage) * 255; // Scale error to PWM units
pwmValue = constrain(pwmValue, 0, 255); // Ensure PWM stays in valid range
analogWrite(pwmPin, pwmValue); // Send PWM to MFC
// Calculate PWM voltage for logging
float pwmVoltage = (pwmValue / 255.0) * fullScaleVoltage;
// ---------------- LOG DATA ----------------
unsigned long currentTime = millis() - startTime;
Serial.print(currentTime); Serial.print(","); // Time in ms
Serial.print(pwmVoltage, 3); Serial.print(","); // PWM voltage
Serial.print(correctedVoltage, 3); Serial.print(","); // Measured voltage
Serial.println(errorVoltage, 3); // Error voltage
// Sampling delay (adjust as needed, 200 ms = 5 Hz)
delay(200);
}
}
Let me also upload an image which explains the connections to the best way I could

As I understand the figures 2.1 in the manual the signal ground should be connected to the controller, not to any other GND. The differential ADC input may provide much better results.
Your code says you use A1, your picture says A0...
Keep the signal wires and gnd wire to analog input together..
Maybe add small cap near analog input. A resistor of 10k to gnd may also help... the manual seems to imply 2k or even less...
It is difficult to follow, but you may have created gnd loops...
It appears that the controller is not responding properly to the code The voltages across the pins are ok, but the valve is not opening properly
regards
Ketan
You're using low pass filtered, 980Hz PWM for a set point signal? How much ripple on that signal (in millivolts)?
Think I would use a 12 bit DAC with a tight reference voltage supply.
Well, the voltage on the Arduino at max is just 5.1V, with the flow controller I am using using a +15 and -15V, and COM being connected to pin 05 and grounded well. The minimum voltage with no flow condition is around 0.01 V. I am using an RC filter of 10Kohm and 10uF for the signal for PWM, with the voltage variation between 0-5V. What is DAC for ? Why would the valve not respond?
regards
Ketan
Hello Everyone, so the interesting thing that I am observing is that the voltage across the inputs and outputs at the pin of the flow controller and also at the Arduino are matching based on requirements giving 100%=5V, 50%=2.5V and 0%=0V, but the valve is not opening properly somehow the valve maybe stuck or I would assume the signal is not going to the valve properly? This is an H-pin out. Any suggestions? I can also share my code if someone would like to have a look and go through the logic. The flow controller is N2-based calibrated, but using H2, and hence the gas correction factor was used in the code, given below is the code:
// -------------------------------
// Arduino Flow Controller with H2 Correction
// -------------------------------
const int pwmPin = 5; // PWM output to flow controller
const int measurePin = 16; // Analog input (A2)
const float gasCorrectionFactor = 1.004; // N2 → H2 correction
void setup() {
pinMode(pwmPin, OUTPUT);
pinMode(measurePin, INPUT);
Serial.begin(9600);
while (!Serial) { ; } // Wait for Serial Monitor
Serial.println("Enter desired flow % (0-100) for H2:");
}
void loop() {
if (Serial.available() > 0) {
int flowPercent = Serial.parseInt();
Serial.read(); // clear newline
// Constrain flow % between 0 and 100
flowPercent = constrain(flowPercent, 0, 100);
// Apply gas correction factor
float correctedFlow = flowPercent * gasCorrectionFactor;
correctedFlow = constrain(correctedFlow, 0, 100); // clamp to 100%
// Map corrected flow % to PWM value (0-255)
int pwmValue = map(correctedFlow, 0, 100, 0, 255);
// Output PWM
analogWrite(pwmPin, pwmValue);
delay(50); // small delay for stabilization
// Read ADC value
int adcValue = analogRead(measurePin); // 0-1023
// Convert ADC to voltage (0-5V)
float measuredVoltage = (adcValue / 1023.0) * 5.0;
// Clamp measured voltage to max 5 V
if (measuredVoltage > 5.0) measuredVoltage = 5.0;
// Calculate expected voltage for H2
float expectedVoltage = (correctedFlow / 100.0) * 5.0;
// Print results
Serial.print("Flow % (H2): "); Serial.print(flowPercent);
Serial.print(" PWM Value: "); Serial.print(pwmValue);
Serial.print(" Expected Voltage: "); Serial.print(expectedVoltage, 2);
Serial.print(" V Measured Voltage: "); Serial.println(measuredVoltage, 2);
Serial.println("\nEnter next desired flow % (0-100) for H2:");
}
}
Thank you for your reply, with no flow condition , I am observing a voltage of 0.01V on the PWM pin, for flow conditions, 50% is giving me 2.5/2.6V and then 100% flow is 5/5.1V output. I have uploaded the wiring diagram below, the wire from the pin12 is removed since, pin 05 and pin 12 is interconnected. For a 100% flow, I am also observing a 5V on the Arduino pin A2(output pin connected to pin 06), but my code is giving different values(probably a code issue I suppose). though the valves are opening.
If you have any questions, let me know. I believe the flow controller works on the principle of creating a pressure difference between input(upstream) and output(downstream). The flow controller is rated at an upstream pressure of 90 psig for the downstream pressure variation between 0-30 psi.