How are you homing the stepper motor?
I have some new code Ill post in case you are interested modifying it. Its more responsive and reacts faster or slower according to how far out of the AFR parameters. This code uses a switch to go from manual pot switch adjust to automatic. Might be easy for you to adapt stepper code in place of the servo code.
There is another version of this that runs from I2C and the servo can be ran via a slider GUI widget or you can simply push full auto mode and it fires up the engine automatically; then it switches into auto adjust mode by itself. There is another control module that goes with it and you can run the entire machine in semi automatic or full auto. Between the two controller running over I2C and the GUI in full Auto mode the controller will take the machine from cold start up, switch all valving and fire the machine off. It can light the flare tube on its own and then go into engine run once it sees temp parameters are met. It also has a fail safe if the reactor temp fall below operating temperature it will shut down on its own. Yeah this is why Im so quiet ive been writing software for a solid four weeks
Edit: Ok Chris I give up it wont cooperate today haha.
#include <Servo.h>
Servo myservo;
// create servo object to control a servo
//VG 02 Wide Band Mixture Controller V1.3
//Craeted by Matt Ryder, Vulcan Gasifier LLC May 5, 2015
//Prior edit; June 22, 2015
//Change log
//April 30,2017 - Todd Harpster
// added contraint to calculated delays after mapping to keep them in range
// read the O2 sensor just once per loop
// add table of expected delays based upon O2 sensor value
//April 30, 2017 - Todd Harpster
// v2 control loop
// refactored code to use mode variable and switch statement to
// This code requires an AEM O2 sensor kit with LSU 4.9 sensor Part # 30-4110
// These constants won't change:
const int O2SensePin = A1; // pin that the O2 sensor is attached to
const int O2SwtPin = A2; //Pin Auto Mode Switch is attached to
const int O2ManPin = A0; // Reads the O2 Manual Adjust Potentiometer on pin A1
// constants for our mode values
const int Mode_Override = 1;
const int Mode_Rich = 2;
const int Mode_Stoichiometric = 3;
const int Mode_Lean = 4;
//tunable parameters below
const int RichCon1 = 700; // Threshold limit for Rich gas condition
const int LeanCon1 = 900; //Threshold limit for lean gas condition
//
const int MinTuningServoPosition = 10; // never fully close the valve in O2 loop mode
const int MaxTuningServoPosition = 180; // wide open
int mode = 0; // loop operating mode
int pos = 0; // variable to store the servo position
int val; // variable to read the value from the analog pin
int lastpos = val; // variable to store the servo last position
int O2SwitchState = 0; // variable for reading the Fuel Mixer Mode status
void setup()
{
myservo.attach(13); // attaches the servo on pin 9 to the servo object
// Need to create a set point for servo start position after manual tuning
{
val = analogRead(O2ManPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // 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
lastpos = val; // sets lastpos to equal the position of the manually set position
delay(10); // waits for the servo to get there
}
}
//
// O2 Sensor Reading Delay
// ================= ====================
// Manual 10
// Rich 0 - 700 variable 500 - 800
// Stoichi 701-899 500
// Lean 900 - 1023 variable 800 - 450
//
void loop()
{
// read the state of the pushbutton value:
O2SwitchState = digitalRead(O2SwtPin);
// read the value of the O2 sensor:
//Todd - read the O2 sensor once for this loop and store in sensorReading
int sensorReading = analogRead(O2SensePin);
//variable to hold mode for this time through the loop
int mode = Mode_Stoichiometric; // assume O2 reading is not too rich or not too lean, just right
int delayms = 500; // 500 ms delay as a default value - it case it doesn't get changed below
if (O2SwitchState == LOW) {
mode = Mode_Override;
} else {
if ( sensorReading <= RichCon1 ) {
mode = Mode_Rich;
}
if (sensorReading >= LeanCon1 ) {
mode = Mode_Lean;
}
}
switch (mode) {
case Mode_Override:
val = analogRead(O2ManPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 180); // 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
lastpos = val; // sets lastpos to equal the position of the manually set position
delayms = 10; // waits for the servo to get there
break;
case Mode_Rich:
// move the air mixture servo to lean out by adding air
lastpos = constrain(lastpos+1, MinTuningServoPosition, MaxTuningServoPosition); // add 1 but make sure it stays in range
myservo.write (lastpos); // tell the servo where to go
val = map(sensorReading, 0, RichCon1, 100, 400); // Richer mixtures get shorter delay
val = constrain( val, 100, 400); // Keep values between 100 and 400 ms
delayms = val + 400; // increase delay so minimum is 500 ms - max is 800 ms
break;
case Mode_Stoichiometric:
delayms = 500; // no need to move servo set delay to check back in 500 ms
break;
case Mode_Lean:
// move the air mixture servo to decrease air to make richer
lastpos = constrain(lastpos-1, MinTuningServoPosition, MaxTuningServoPosition); // subtract 1 but make sure it stays in range
myservo.write (lastpos); // tell the servo where to go
val = map(sensorReading, 1023, LeanCon1, 450, 800); // the leaner the mixture the shorter the delay - need to adjust quickly
val = constrain(val, 450, 800); // keep the delay between 450 and 800 ms
delayms = val;
break;
otherwise:
//this shouldn't happen
break;
}
//wait for a little bit before doing this again
delay(constrain(delayms,250,1250)); // use contrain to be completely sure delay value is reasonable
}