-
Notifications
You must be signed in to change notification settings - Fork 1
/
correct_flow_rate_calculator.ino
146 lines (122 loc) · 6.61 KB
/
correct_flow_rate_calculator.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// written by BingAI
//code implements self calibrating linearization function for LPG gas computer program, as well as the additional predictor function for gas pressure. I will also implement variables that allow applying dynamic corrections based on the input parameters.
//It assumes that you have already defined the constants and variables for the sensor readings, such as gas pressure, temperature, injector pulse width, nozzle diameter, injections per minute, and manifold pressure.
//It uses some dummy names for them, but you can change them according to your code.
// Define the constants and variables for the linearization function
const float K = 0.008314; // Universal gas constant in kJ/(mol*K)
const float M = 0.044; // Molar mass of LPG in kg/mol
const float A = 0.25 * PI * sq(nozzle_diameter); // Cross-sectional area of the nozzle in m^2
float gas_volume; // Gas volume in m^3
float gas_density; // Gas density in kg/m^3
float flow_rate; // Flow rate in kg/s
// Define the constants and variables for the predictor function
const float P0 = 1.01325; // Atmospheric pressure in bar
float P1; // Gas pressure in bar
float P2; // Manifold pressure in bar
float delta_P; // Pressure difference between gas and manifold in bar
// Define the constants and variables for the dynamic corrections
const int N = 10; // Number of elements in the correction tables and arrays
float vacuum_table[N]; // Table of vacuum values in kPa
float pressure_table[N]; // Table of pressure values in bar
float correction_table[N]; // Table of correction factors
float vacuum_array[N]; // Array of vacuum values in kPa
float pressure_array[N]; // Array of pressure values in bar
float correction_array[N]; // Array of correction factors
int index; // Index of the current element in the arrays
float vacuum; // Vacuum value in kPa
float pressure; // Pressure value in bar
float correction; // Correction factor
// Define a function to interpolate between two values
float interpolate(float x, float x1, float x2, float y1, float y2) {
return y1 + (x - x1) * (y2 - y1) / (x2 - x1);
}
// Define a function to find the index of the closest value in a table or array
int find_index(float x, float table_or_array[]) {
int i;
for (i = 0; i < N - 1; i++) {
if (x >= table_or_array[i] && x <= table_or_array[i + 1]) {
break;
}
}
return i;
}
// Define a function to calculate the gas volume from gas pressure and temperature
void calculate_gas_volume() {
gas_volume = K * gas_temperature * P1 / (M * P0); // Ideal gas law
}
// Define a function to calculate the gas density from gas pressure and temperature
void calculate_gas_density() {
gas_density = M * P0 / (K * gas_temperature * P1); // Inverse of ideal gas law
}
// Define a function to calculate the flow rate from injector pulse width, nozzle diameter and injections per minute
void calculate_flow_rate() {
flow_rate = A * sqrt(2 * delta_P * P0 * 100000 / gas_density) * injector_pulse_width / 1000 * injections_per_minute / 60; // Bernoulli's equation
}
// Define a function to calculate the pressure difference between gas and manifold
void calculate_pressure_difference() {
delta_P = P1 - P2; // Simple subtraction
}
// Define a function to calculate the gas pressure from manifold pressure and vacuum line influence
void calculate_gas_pressure() {
P1 = P2 + vacuum * correction; // Linear relation with correction factor
}
// Define a function to update the correction tables and arrays based on the sensor readings
void update_corrections() {
index = find_index(vacuum, vacuum_table); // Find the index of the closest vacuum value in the table
correction = interpolate(vacuum, vacuum_table[index], vacuum_table[index + 1], correction_table[index], correction_table[index + 1]); // Interpolate the correction factor from the table
for (int i = N - 1; i > 0; i--) { // Shift the elements in the arrays to the left by one position
vacuum_array[i] = vacuum_array[i - 1];
pressure_array[i] = pressure_array[i - 1];
correction_array[i] = correction_array[i - 1];
}
vacuum_array[0] = vacuum; // Store the current vacuum value in the first position of the array
pressure_array[0] = pressure; // Store the current pressure value in the first position of the array
correction_array[0] = correction; // Store the current correction factor in the first position of the array
}
// Define a function to apply the dynamic corrections based on the arrays
void apply_corrections() {
float sum_vacuum = 0; // Sum of the vacuum values in the array
float sum_pressure = 0; // Sum of the pressure values in the array
float sum_correction = 0; // Sum of the correction factors in the array
for (int i = 0; i < N; i++) { // Loop through the elements in the arrays
sum_vacuum += vacuum_array[i];
sum_pressure += pressure_array[i];
sum_correction += correction_array[i];
}
float average_vacuum = sum_vacuum / N; // Average of the vacuum values in the array
float average_pressure = sum_pressure / N; // Average of the pressure values in the array
float average_correction = sum_correction / N; // Average of the correction factors in the array
P1 = average_pressure + average_vacuum * average_correction; // Adjusted gas pressure with dynamic corrections
}
// Define a function to perform all the calculations and corrections
void perform_calculations() {
calculate_gas_volume(); // Calculate the gas volume from gas pressure and temperature
calculate_gas_density(); // Calculate the gas density from gas pressure and temperature
calculate_pressure_difference(); // Calculate the pressure difference between gas and manifold
calculate_flow_rate(); // Calculate the flow rate from injector pulse width, nozzle diameter and injections per minute
calculate_gas_pressure(); // Calculate the gas pressure from manifold pressure and vacuum line influence
update_corrections(); // Update the correction tables and arrays based on the sensor readings
apply_corrections(); // Apply the dynamic corrections based on the arrays
}
// Define a function to print out the results
void print_results() {
Serial.print("Gas volume: ");
Serial.print(gas_volume);
Serial.println(" m^3");
Serial.print("Gas density: ");
Serial.print(gas_density);
Serial.println(" kg/m^3");
Serial.print("Flow rate: ");
Serial.print(flow_rate);
Serial.println(" kg/s");
Serial.print("Gas pressure: ");
Serial.print(P1);
Serial.println(" bar");
}
// Define a function to run in loop
void loop() {
//TODO: implement read_sensors function
//TODO: implement synchronize_to_injector function
perform_calculations(); // Perform all the calculations and corrections
print_results(); // Print out the results
}