const int nitrous1Pin = 9; // Nitrous1 control pin
const int fuel1Pin = 10; // Fuel1 control pin
const int nitrous2Pin = 11; // Nitrous2 control pin
const int fuel2Pin = 12; // Fuel2 control pin
const int triggerPin = 2; // Trigger input pin is from Wide Open throttle switch
//------------------------------------------------------------------------------------------------------------------------------------
// **************************************Nothing Above this line should be edited!!!!!!!**********************************************
// Block sets the Hertz the Solenoids are controlled at. Adjust settings to what your system works with. Too high a setting will
// not allow solenoid to operate correctly. Too low and the solenoid will not flow as smooth of a pressure curve after solenoid
// Range of values can be between 12 and 25 hertz
//Typical starting values are
// 15 Hertz for trash can style nitrous solenoids
// 18 for smaller nitrous solenoids up to .125 orifice
// 18-20 for Fuel solenoids
// Higher amp solenoids can make use of a higher hertz value typically
const int frequencyNitrous1 = 15; // Frequency for Nitrous1 in Hz
const int frequencyFuel1 = 15; // Frequency for Fuel1 in Hz
const int frequencyNitrous2 = 15; // Frequency for Nitrous2 in Hz
const int frequencyFuel2 = 15; // Frequency for Fuel2 in Hz
// Second block controls the delay time after WOT switch is activated before each stage and/or set of solenoids start pulsing nitrous.
const unsigned long delayNitrous1 = 0; // Delay in milliseconds for Nitrous1 to start
const unsigned long delayFuel1 = 0; // Delay in milliseconds for Fuel1 to start
const unsigned long delayNitrous2 = 1000; // Delay in milliseconds for Nitrous2 to start
const unsigned long delayFuel2 = 1000; // Delay in milliseconds for Fuel2 to start
// The [30] number below indicates the ramp time. 30 equals 3.00 seconds total (30 x 0.10 seconds = 3.00 seconds)
// The 30 can be changed to a higher number to make a longer ramp. Add more % numbers with comma.
// Define the duty cycle percentages for each 0.1 second interval for Nitrous1
// First stage Nitrous control
const int dutyCycleNitrous1[30] = {
20, 20, 20, 30, 30, //Each line is half a second of ramp
35, 40, 40, 50, 55,
60, 60, 60, 60, 70,
70, 80, 85, 90, 90,
100, 100, 100, 100, 100,
100, 100, 100, 100, 100
};
// Define the duty cycle percentages for each 0.1 second interval for Fuel1
// First stage Fuel control
const int dutyCycleFuel1[30] = {
20, 20, 20, 30, 30, //Each line is half a second of ramp
35, 40, 40, 50, 55,
60, 60, 60, 60, 70,
70, 80, 85, 90, 90,
100, 100, 100, 100, 100,
100, 100, 100, 100, 100
};
// Define the duty cycle percentages for each 0.1 second interval for Nitrous2
// Second stage of Nitrous control
const int dutyCycleNitrous2[30] = {
20, 20, 20, 30, 30, //Each line is half a second of ramp
35, 40, 40, 50, 55,
60, 60, 60, 60, 70,
70, 80, 85, 90, 90,
100, 100, 100, 100, 100,
100, 100, 100, 100, 100
};
// Define the duty cycle percentages for each 0.1 second interval for Fuel2
// Second stage Fuel control
const int dutyCycleFuel2[30] = {
20, 20, 20, 30, 30, //Each line is half a second of ramp
35, 40, 40, 50, 55,
60, 60, 60, 60, 70,
70, 80, 85, 90, 90,
100, 100, 100, 100, 100,
100, 100, 100, 100, 100
};
// **************************************Nothing Below this line should be edited!!!!!!!**********************************************
//------------------------------------------------------------------------------------------------------------------------------------
const unsigned long cycleDurationNitrous1 = 1000 / frequencyNitrous1; // Duration of one PWM cycle in milliseconds for Nitrous1
const unsigned long cycleDurationFuel1 = 1000 / frequencyFuel1; // Duration of one PWM cycle in milliseconds for Fuel1
const unsigned long cycleDurationNitrous2 = 1000 / frequencyNitrous2; // Duration of one PWM cycle in milliseconds for Nitrous2
const unsigned long cycleDurationFuel2 = 1000 / frequencyFuel2; // Duration of one PWM cycle in milliseconds for Fuel2
void setup() {
pinMode(nitrous1Pin, OUTPUT); // Set Nitrous1 pin as output
pinMode(fuel1Pin, OUTPUT); // Set Fuel1 pin as output
pinMode(nitrous2Pin, OUTPUT); // Set Nitrous2 pin as output
pinMode(fuel2Pin, OUTPUT); // Set Fuel2 pin as output
pinMode(triggerPin, INPUT); // Set trigger pin as input
digitalWrite(nitrous1Pin, LOW); // Ensure Nitrous1 is initially off
digitalWrite(fuel1Pin, LOW); // Ensure Fuel1 is initially off
digitalWrite(nitrous2Pin, LOW); // Ensure Nitrous2 is initially off
digitalWrite(fuel2Pin, LOW); // Ensure Fuel2 is initially off
}
void loop() {
// Wait for trigger signal to go high
while (digitalRead(triggerPin) == LOW) {
delay(10);
}
// Trigger signal detected, start PWM cycle
unsigned long startTime = millis();
for (int i = 0; i < 30; i++) {
if (digitalRead(triggerPin) == LOW) {
// If trigger signal is lost, turn off relays and break out of the loop
digitalWrite(nitrous1Pin, LOW);
digitalWrite(fuel1Pin, LOW);
digitalWrite(nitrous2Pin, LOW);
digitalWrite(fuel2Pin, LOW);
break;
}
unsigned long intervalStartTime = millis();
unsigned long onTimeNitrous1 = cycleDurationNitrous1 * dutyCycleNitrous1[i] / 100;
unsigned long offTimeNitrous1 = cycleDurationNitrous1 - onTimeNitrous1;
unsigned long onTimeFuel1 = cycleDurationFuel1 * dutyCycleFuel1[i] / 100;
unsigned long offTimeFuel1 = cycleDurationFuel1 - onTimeFuel1;
unsigned long onTimeNitrous2 = cycleDurationNitrous2 * dutyCycleNitrous2[i] / 100;
unsigned long offTimeNitrous2 = cycleDurationNitrous2 - onTimeNitrous2;
unsigned long onTimeFuel2 = cycleDurationFuel2 * dutyCycleFuel2[i] / 100;
unsigned long offTimeFuel2 = cycleDurationFuel2 - onTimeFuel2;
while (millis() - intervalStartTime < 100) {
unsigned long currentTime = millis() - startTime;
if (digitalRead(triggerPin) == LOW) {
// If trigger signal is lost, turn off relays and exit the loop immediately
digitalWrite(nitrous1Pin, LOW);
digitalWrite(fuel1Pin, LOW);
digitalWrite(nitrous2Pin, LOW);
digitalWrite(fuel2Pin, LOW);
return;
}
// Nitrous1 control
if (currentTime >= delayNitrous1 && millis() % cycleDurationNitrous1 < onTimeNitrous1) {
digitalWrite(nitrous1Pin, HIGH);
} else {
digitalWrite(nitrous1Pin, LOW);
}
// Fuel1 control
if (currentTime >= delayFuel1 && millis() % cycleDurationFuel1 < onTimeFuel1) {
digitalWrite(fuel1Pin, HIGH);
} else {
digitalWrite(fuel1Pin, LOW);
}
// Nitrous2 control
if (currentTime >= delayNitrous2 && millis() % cycleDurationNitrous2 < onTimeNitrous2) {
digitalWrite(nitrous2Pin, HIGH);
} else {
digitalWrite(nitrous2Pin, LOW);
}
// Fuel2 control
if (currentTime >= delayFuel2 && millis() % cycleDurationFuel2 < onTimeFuel2) {
digitalWrite(fuel2Pin, HIGH);
} else {
digitalWrite(fuel2Pin, LOW);
}
}
}
// Maintain relays ON after reaching 100% duty cycle
digitalWrite(nitrous1Pin, HIGH);
digitalWrite(fuel1Pin, HIGH);
digitalWrite(nitrous2Pin, HIGH);
digitalWrite(fuel2Pin, HIGH);
while (digitalRead(triggerPin) == HIGH) {
delay(10);
}
// Turn off relays when trigger signal is lost
digitalWrite(nitrous1Pin, LOW);
digitalWrite(fuel1Pin, LOW);
digitalWrite(nitrous2Pin, LOW);
digitalWrite(fuel2Pin, LOW);
}
// The stages are named to idependently control the nitous and fuel solenoids to keep proper Nitrous to fuel ratio
// 4 stages = N and F solenoids for 2 stages. This is needed so while progressing there is not a lean conditiion on bigger tune ups.
// A common place to start would be 10% more on fuel ramp vs the nitrous ramp. EX. 30% nitrous = 40% fuel.
// This can be adjusted to the needs of your system. If recording with a Racepak an extreme lean condition
// can result in O2 reading being lean and quick dips in G-Meter early in the run.
// The frequency in HZ should end up between 12 to 25 HZ. Bigger solenoids are harder to control at higher
// hertz rates. Here are common starting points for hz settings. Note higher amp solenoids can generally react
// quicker than low amp models
// trash can nitrous = 15
// .125 nitrous = 18
// Most fuel = 18-20
// Typical percentages work in much the same way in that there are threshold too low to operate and too high to slow down much flow.
// Opening percentages are dependent on type of solenoids but most will work at 20%.
// You can test if yours will operate at a lower percent.
// Most sytems will come close to 100% flow at 80%-90% duty cycle on controller. Depending on systems pounds per hour flow
// DO NOT!!!! hook solenoids directly to controller. Use a high amp solid state relay for control stage. Controls 4 total
// Controller outputs a High signal of 5 volts to activate relay (SSR only)
// The following is the pin out for controller
// D9 output hooks up to Nitrous stage 1 SSR input
// D10 output hooks up to Fuel stage 1 SSR input
// D11 output hooks up to Nitrous stage 2 SSR input
// D12 output hooks up to Fuel stage 2 SSR input
// D2 is input from Wide Open Throttle switch. Needs to be between 2.5 minimum to 5 volts max
// recommend a pull down resistor of 10k ohms on D2 to pull pin low for safety
// This pregressive controller works on same principle of others on the market in that it has no way of
// distinguishing what jets are in your system. So for example 30% does not equal 30% of nitrous flow
// It only means the duty cycle or on time for solenoid is 30%.
// Also remember that depending on jet sizes the solenoids may fill block to max flow back pressure.
// Meaning that a smaller jet will flow a real 100% sooner than larger jets due to the solenoids operating
// fast enough to fill nitrous supply demand of the jets in your system.
// Parameters of controller is a total ramp time of 3.00 seconds with the ability to adjust the percentage of duty cycle every 0.10 seconds
// This should be enough control to control any car and system. If a longer ramp is needed and/or a finer resolution of adjustment
// I can modify the main program to meet these needs.