Components and supplies
Bosch stationairy valve
lamba sensor
Arduino Nano
Air/Fuel Ratio Gauge
Apps and platforms
Arduino IDE
Project description
Code
O2 valve experiment
cpp
1// o2 valve experiment by R.Bos 30-6-2024 2// 3 #include <GyverPWM.h> 4 5 6 const int pwm1 = 9;//5;//pwm output to open valve 7 const int pwm2 = 10;//6;//pwm output to close valve 8 const int pot1 = A2;//potmeter 0V---1V 9 const int sensor = A0;//O2 sensor 10 const int hall_1 = 2;//hall sensor for rpm 11 const int ledPin = A5;//LED_BUILTIN; 12 const int dpswitch = 7; 13 const int offswitch = 8;//A4; 14 const int meter = 11; 15 const int rly = 12; 16 int valpot = 0;int valpotold = 0;int valpot1 = 0; 17 int prcold = 0; int diff = 0; 18 int prc = 0; 19 int valve1 = 0 ;int valve2 = 64; 20 int i; int sft = 0;//shift O2 to lower side 21 int wait = 0; 22 unsigned long timeoff; 23 unsigned long timeoffold; 24 unsigned long timeloop; 25 unsigned long timeloopold; 26 unsigned long print1time; 27////////// for rpmcounter ///////////////////// 28 unsigned long rpm = 0; 29 unsigned long revtime = 0; 30 unsigned long revtimeold = 0; 31 volatile unsigned long pulses = 0; 32 volatile unsigned long rpm1 = 0; 33 unsigned int pulses1 = 0; 34 unsigned int d1 = 16;// number of pulses before time taken (timerpm) 35 float revtime1 = 0;//if d1 = 16 , time is for 4 revolutions 36///////////// for o2 //////////////////////////////// 37 unsigned long O2; 38 int mV10[11];// 10*50mS = 500mS 39 int mV200[21];//20*500mS = 10 sec 40 unsigned long mV1; 41 unsigned long mV2; 42 unsigned long mV1ava; 43 unsigned long mV2ava; 44 unsigned long mV1old; 45 unsigned long mV2old; 46 int bb = 0; int bbb = 0; 47 int Vin = 5000;//4800mV supply voltage , needed for reference , normal 5000mV , laptop only 4740mV 48 unsigned long waittime; 49//////////////// for switch and led /////////////////////////////////////////////// 50 int ledState = LOW; 51 unsigned long blinktime; 52 int interval = 1500; 53 int ll; int dp = 1;int dpx; 54 int dpoff = 1; 55 unsigned long valout; 56 int valin; 57////////////////////////////////////////////////////////////////////////////////// 58 59void setup()////////////////////////////////////////////////////////////////////// 60{ 61 Serial.begin(9600); 62 pinMode(pwm1,OUTPUT); 63 pinMode(pwm2,OUTPUT); 64 pinMode(hall_1,INPUT); 65 pinMode(ledPin,OUTPUT); 66 pinMode(dpswitch,INPUT_PULLUP); 67 pinMode(offswitch,INPUT_PULLUP); 68 pinMode(meter,OUTPUT); 69 pinMode(rly,OUTPUT); 70 pinMode(pot1,INPUT_PULLUP); 71 attachInterrupt(0, rpmcounter, FALLING); 72 timeloop = millis(); 73 PWM_frequency(9, 8000, FAST_PWM); 74 PWM_frequency(10, 8000, FAST_PWM); 75 PWM_set(pwm1,0); 76 PWM_set(pwm2,64); 77 digitalWrite(rly,1); 78 //analogWrite(pwm1,0); analogWrite(pwm2,64); 79 80} 81 82void print1()/////////////////////////////////////////////////////////////////// 83////////for coding and debugging only/////////////////////////////////////////// 84{ 85 //mV =(( O2 * 473) / 1024) * 10; 86 //mV =( O2 * 4730) / 1024); 87 if(millis() - print1time >= 500){ 88 //Serial.print("mV1 =");Serial.print(mV1); 89 //Serial.print(" mV2 =");Serial.println(mV2); 90 Serial.print("rpm = ");Serial.println(rpm); 91 //Serial.print(" revtime =");Serial.println(revtime); 92 //Serial.print(" waittime =");Serial.println(waittime); 93 //Serial.print("valin =");Serial.print(valin); 94 //Serial.print(" valout =");Serial.println(valout); 95 //Serial.print("dp =");Serial.println(dp); 96 //Serial.print("prc =");Serial.print(prc); 97 //Serial.print("millivolt =");Serial.println(mV); 98 //Serial.print("valve1 = ");Serial.print(valve1); 99 //Serial.print(" valve2 = ");Serial.println(valve2); 100 //Serial.print("timeloopold =");Serial.println(timeloopold); 101 //Serial.print("revtime =");Serial.println(revtime); 102 print1time = millis(); 103 } 104 } 105 106void loop()///////////////////////////////////////////////////////////////////// 107{ 108 rpm = rpm1; revtime = revtime1;// / (d1 / 16);// reactiontime is 4*4 pulses = 4 cycles 109 if(rpm == 0 ){revtime = 400;} 110 if(revtime < 100){revtime = 100;}//without Rpm input could be set at a fixed timing between 100 and 400ms 111 getO2valu(); 112 //waittimeold = millis() - waittime; 113 if(millis() - waittime >= revtime){ 114 if(rpm < 750){stationair();} else { 115 if(mV2 > 520){sft = 30;} else { 116 if(mV2 < 490){sft = 0;}} 117 if(mV1 > 500){rich3();} 118 if(mV1 < 500){lean3();}} 119 mV1old = mV1; mV2old = mV2;} 120 //valpot = analogRead(pot1); 121 //prc = map(valpot,0,202,0,100); 122 if(digitalRead(offswitch) == 0 || dpoff == 0){digitalWrite(rly,0);if(prcold != 0){prc = prc - 30;} else {prc = 0;}} 123 if(digitalRead(offswitch) != 0 || dpoff == 1){digitalWrite(rly,1);} 124 if(rpm < 400){if(prcold != 0){prc = prc - 30;} else {prc = 0;}} 125 prc = constrain(prc,0,100); 126 if(prc < prcold){diff = prcold - prc; valveclose();waittime = millis();} 127 if(prc > prcold){diff = prc - prcold; valveopen();waittime = millis();} 128 if(valve2 < 195 && valve1 < 195){wait = 0;timeoff = 0;} else{valveoff();} 129 Select2(); 130 //if(dp == 1){valout = map(valin,0,234,0,285) ;} 131 if(dp == 1){valout = (valin * 5) / 4 ;} //input O2 sensor = output 132 if(dp == 2){valout = (((mV1 * 1024) / Vin) * 5 ) / 4;}//shortterm average output 133 if(dp == 3){valout = (((mV2 * 1024) / Vin) * 5 ) / 4;}//longterm average output 134 if(dp == 4){valout = map(prc,0,100,13,255);} //valve position output 135 valout = constrain(valout,0,255);analogWrite(meter,valout);//gauge output only 136 //print1();//coding and debugging only , it will disturb ISR of hall sensor input 137 led1(); 138 timeloopold = millis() - timeloop; 139 if(timeloopold < 50){delay(50 - timeloopold);}//looptime fixed at 50ms 140 timeloop = millis(); 141 142} 143void rich3()///////////////////////////////////////////////////////////////////// 144{ 145 if(mV1 < mV1old && mV1 >= 600){prc = prc - 5;} else { 146 if(mV1 < mV1old && mV1 < 600){prc = prc - 1;} else { 147 if(mV1 > 550 - sft){prcmin();prc = prc + 1;} 148 if(mV1 > 600 - sft){prc = prc + 1;} 149 if(mV1 > 650 - sft){prc = prc + 1;} 150 if(mV1 > 700 - sft){prc = prc + 2;} 151 if(mV1 > 750 - sft){prc = prc + 3;}}} 152 if(mV2 < mV2old && mV2 >= 600){prc = prc - 2;} else { 153 if(mV2 > 550){prc = prc + 1;} 154 if(mV2 > 600){prc = prc + 1;} 155 if(mV2 > 650){prc = prc + 1;} 156 if(mV2 > 700){prc = prc + 2;} 157 if(mV2 > 750){prc = prc + 3;}} 158} 159void lean3()///////////////////////////////////////////////////////////////////// 160{ 161 //if(mV1 > mV1old && mV1 > 300){prc = prc + 1;} else { 162 if(mV1 < 450){prcmax();prc = prc - 1;} 163 if(mV1 < 400){prc = prc - 1;} //-1 164 if(mV1 < 350){prc = prc - 2;} //-1 165 if(mV1 < 300){prc = prc - 3;} //-2 166 if(mV1 < 250){prc = prc - 8;} //-3 167 if(mV1 < 200){prc = prc = 0;} 168 //if(mV2 < 450){prc = prc - 1;} //-1 169 if(mV2 < 400){prc = prc - 2;} //-1 170 if(mV2 < 350){prc = prc - 2;} //-1 171 if(mV2 < 300){prc = prc - 2;} //-2 172 if(mV2 < 250){prc = prc - 3;} //-3 173 if(mV2 < 200){prc = prc = 0;} 174} 175void prcmax()//////////////////////////////////////////////////////////////////// 176{ 177 if(prcold==100){if(rpm >= 2500){prc = 40;} else{ 178 if(rpm >= 1500 && rpm < 2500){prc = 50;}else{ 179 if(rpm < 1500){prc = 60;}}}} 180} 181void prcmin()////////////////////////////////////////////////////////////////////// 182{ 183 if(prcold == 0){if(rpm >= 2500){prc = 40;} else{ 184 if(rpm >= 1500 && rpm < 2500){prc = 30;}else{ 185 if(rpm < 1500){prc = 20;}}}} 186} 187void stationair()////////////////////////////////////////////////////////////////// 188{ 189 if(mV1 > 800){prcmin();prc = prc + 1;} 190 //if(mV1 > 750){prc = prc + 2;} 191 //if(mV1 > 800){prc = prc + 3;} 192 if(mV1 > 850){prc = prc + 2;} 193 //if(mV2 > 700){prc = prc + 2;} 194 //if(mV2 > 750){prc = prc + 2;} 195 if(mV2 > 800){prc = prc + 1;} 196 if(mV2 > 850){prc = prc + 2;} else{ 197 if(mV1 < 750){prcmax();prc = prc - 2;} 198 if(mV1 < 700){prc = prc - 2;} 199 if(mV1 < 650){prc = prc - 10;} 200 //if(mV1 < 600){prc = prc - 4;} 201 if(mV2 < 750){prc = prc - 2;} 202 if(mV2 < 700){prc = prc - 2;} 203 if(mV2 < 650){prc = 0;} 204 //if(mV2 < 600){prc = prc - 4;} 205 } 206 if(prc > 60){prc = 60;} 207 208} 209 210void getO2valu()//////////////////////////////////////////////////////////////// 211{ 212 O2 = analogRead(sensor); valpot = O2; valin = O2; O2 = ( O2 * Vin) / 1024; 213 //O2 = map(O2,0,1024,0,Vin); 214 bb++; 215 mV1ava =(mV1ava + O2) - mV10[bb]; 216 mV1 = mV1ava / 10; // 217 mV10[bb] = O2; 218 if(bb >= 10){bb = 0;bbb++; 219 mV2ava =(mV2ava + mV1) - mV200[bbb]; 220 mV2 = mV2ava / 20; 221 mV200[bbb] = mV1; 222 if(bbb >= 20){bbb = 0;} 223 } 224} 225 226void valveclose()////////////////////////////////////////////////////////////// 227{ 228 for(i = 0; i < (diff + 1);i++) 229 {valve1 = map(prcold,0,100,60,195);valve1 = constrain(valve1,0,255); 230 valve2 = map(prcold,0,100,195,60);valve2 = constrain(valve2,0,255); 231 PWM_set(pwm1,valve1);PWM_set(pwm2,valve2); 232 //analogWrite(pwm2,valve2);analogWrite(pwm1,valve1); 233 prcold--;} 234 //delay(1);} 235 prcold = prc; 236} 237void valveopen()/////////////////////////////////////////////////////////////// 238{ 239 for(i = 0; i < (diff + 1);i++) 240 {valve1 = map(prcold,0,100,60,195);valve1 = constrain(valve1,0,255); 241 valve2 = map(prcold,0,100,195,60);valve2 = constrain(valve2,0,255); 242 PWM_set(pwm1,valve1);PWM_set(pwm2,valve2); 243 //analogWrite(pwm1,valve1); analogWrite(pwm2,valve2); 244 prcold++;} 245 //delay(1);} 246 prcold = prc; 247} 248void valveoff()//////////////////////////////////////////////////////// 249{ 250 if(valve2 == 195 && wait == 0){timeoffold = millis();wait = 1;} 251 if(valve2 == 195 && timeoff >= 1000){wait = 0;timeoff = 0; 252 valve1 = 0;valve2 = 64; 253 PWM_set(pwm1,valve1);PWM_set(pwm2,valve2);} 254 //analogWrite(pwm1,valve1); delay(3);analogWrite(pwm2,valve2);}//valve close 255 if(valve1 == 195 && wait == 0){timeoffold = millis();wait = 1;} 256 if(valve1 == 195 && timeoff >= 1000){wait = 0;timeoff = 0; 257 valve1 = 64;valve2 = 0; 258 PWM_set(pwm1,valve1);PWM_set(pwm2,valve2);} 259 //analogWrite(pwm2,valve2); delay(3);analogWrite(pwm1,valve1);}//valve open 260 if(wait == 1){timeoff = millis() - timeoffold;} 261 262} 263void rpmcounter()////////////////////////////////////////////////////// 264{ 265 pulses++; 266 if(pulses >= d1){ 267 revtime1 = (millis() - revtimeold); 268 revtimeold = millis(); 269 //pulses1 = pulses; 270 pulses = 0; 271 rpm1 = (1000.0/revtime1)*60.0; 272 rpm1 = rpm1 * (d1/4); 273 //d1time(); 274 } 275} 276void d1time()///////////////////////////////// 277//not used in this code , was to stabilize rpm output on oled display 278{ 279 if(rpm1 < 400){d1 = 16;} 280 if(rpm1 >= 400){d1 = 16;} 281 if(rpm1 >= 1000){d1 = 32;} 282 if(rpm1 >= 2000){d1 = 48;} 283 if(rpm1 >= 3000){d1 = 64;} 284} 285void Select()////////////////////////////////////////////////////////// 286{ 287 if(digitalRead(dpswitch) == 0 && dpx >= 1){delay(10);dpx = 2;} 288 if(digitalRead(dpswitch) == 0 && dpx == 0){delay(10); 289 dp++; dpx++; 290 if(dp > 4){dp = 1;} 291} 292 if(digitalRead(dpswitch) != 0 && dpx != 0){ 293 dpx = 0;} 294} 295void Select2()///////////////////////////////////////////////////////// 296{ 297 valpot = analogRead(pot1); 298 if (valpot < 99) { // groud 0 ohm 299 dp = 1; dpoff = 1; 300 } 301 if (valpot > 110 && valpot < 150) { // resistor 4K7 = 130 302 dp = 2; dpoff = 1; 303 } 304 if (valpot > 320 && valpot < 360) { // resistor 18K = 340 305 dp = 3; dpoff = 1; 306 } 307 if (valpot > 545 && valpot < 585) { // resistor 47K = 565 308 dp = 4; dpoff = 1; 309 } 310 if (valpot > 715 && valpot < 755) { // resistor 100K = 735 311 dp = 4; dpoff = 0; 312 } 313 if (valpot > 995) { // open , pullup only = 1015 314 dp = 1; dpoff = 0; 315 } 316} 317void led1()//////////////////////////////////////////////////////////// 318{ 319 if(dpoff == 0){digitalWrite(ledPin,0);} else { 320 if(millis() - blinktime >= interval){blinktime = millis(); 321 if(ledState == LOW){ledState = HIGH; interval = 150;} else{ 322 ledState = LOW; interval = 300;ll++;} 323 digitalWrite(ledPin,ledState);} 324 if(ll >= dp){ll = 0;interval = 2000;}} 325 326}
Comments
Only logged in users can leave comments
jeight1040
6 months ago
I have been searching for a way to fix my carburetor equipped single cylinder motorcycle. i bought a drz400 this summer and thought i got a smoking deal turns out the carb needs work and a new one is 1300 bucks. so i have been searching the web for ideas
jeight1040
6 months ago
do u think this could be integrated
rebos
6 months ago
No , it will not fix a bad carburetor , you better rebuild the carburetor. Something like this project would be too complicated for a motorcycle anyway , there is not enough room I think.
stellargarden
6 months ago
so nice
rebos
4 Followers
•1 Projects
3
5
Air/Fuel controller for LPG engines | Arduino Project Hub
rebos
6 months ago
No , it will not fix a bad carburetor, you better rebuild the carburetor. Something like this project would be to complicated for a motorcycle anyway , there is not enough room I think.