02 Montery Dakar build / final stages

my teams graph


Here's a chart that illustrates the relationship between RPM and PWM duty cycle as defined in your code:

- **X-Axis**: RPM (from 0 to 4000 RPM)
- **Y-Axis**: PWM Value (from 102 to 242, corresponding to 40% to 95% duty cycle)

### Explanation:

- The `mapRPMToPWM` function maps the RPM values to PWM values linearly.
- At 0 RPM, the PWM duty cycle is at 95% (PWM value 242).
- At 4000 RPM, the PWM duty cycle is at 40% (PWM value 102).
- The graph shows a linear decrease in PWM value as RPM increases.

This chart helps visualize how the PWM output will change based on the RPM of the crankshaft, which is crucial for controlling the VVT system accurately. If you have any further questions or need additional modifications, feel free to ask!

1722209131933.png
 
drives nice so far. going to do some down the road heat cycles and see what my impact hammer did not torque appropriately.

also i got my VVT controller ready to potentially allah ackbar some valves

 
for anyone from the future needing this info on a "2009-2012 ford escape duratec 3.0l VVT cam hall sensor wiring pin out diagram" lol
your welcome!
 

Attachments

  • HallPins.JPG
    HallPins.JPG
    134.4 KB · Views: 3
oh baby!
when it drops below 100 outside i can test drive my arduino VVT controller :giggle:
fully customizable
i will be tuning by the seat of my pants
what it looks like....
1722819580433.png



the code my team has made

Code:
const byte analogPin = A0;   // Analog pin connected to the Hall sensor
const byte pwmPin1 = 9;      // PWM output pin 1
const byte pwmPin2 = 10;     // PWM output pin 2

volatile unsigned long pulseStartTime = 0;  // Start time for pulse measurement
volatile unsigned long pulseEndTime = 0;    // End time for pulse measurement
volatile byte pulseCount = 0;               // Counter for pulses
const int threshold = 716;                  // Analog threshold value for 3.5V

unsigned long previousMillis = 0;  // Stores the last time the loop ran
const long interval = 10;          // Desired interval in milliseconds

void setup() {
  Serial.begin(9600);
  pinMode(analogPin, INPUT);
  pinMode(pwmPin1, OUTPUT);
  pinMode(pwmPin2, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  // Check if the desired interval has passed
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;  // Save the last time the loop ran

    int sensorValue = analogRead(analogPin);  // Read the analog value from the sensor

    // Check for falling edge (voltage drop)
    if (sensorValue < threshold) {
      if (pulseCount == 0) {
        pulseStartTime = micros();  // Start timing when the first pulse is detected
      }

      pulseCount++;  // Increment pulse count

      // Check if four pulses have been detected
      if (pulseCount == 4) {
        pulseEndTime = micros();  // End timing after the fourth pulse
        unsigned long timeInterval = pulseEndTime - pulseStartTime;

        // Calculate RPM from the time interval of four pulses
        float crankshaftRPM = calculateCrankshaftRPM(timeInterval);
        int pwmValue = mapRPMToPWM(crankshaftRPM);
        analogWrite(pwmPin1, pwmValue);
        analogWrite(pwmPin2, pwmValue);

        // Print the RPM and the corresponding PWM percentage
        float pwmPercentage = (pwmValue / 255.0) * 100.0;
        Serial.print("RPM: ");
        Serial.print(crankshaftRPM);
        Serial.print(" | PWM: ");
        Serial.print(pwmPercentage);
        Serial.println("%");

        pulseCount = 0;  // Reset pulse count for the next measurement
      }

      // Wait until the signal rises above the threshold again
      while (analogRead(analogPin) < threshold) {
        delay(1);  // Small delay to avoid busy-waiting
      }
    }
  }
}

float calculateCrankshaftRPM(unsigned long interval) {
  // Calculate RPM from the time interval for four pulses
  // Multiply by 2 because the camshaft is at half the speed of the crankshaft
  // 1,000,000 us in a second, 60 seconds in a minute, 4 pulses per revolution

  // The previous correction factor was 980 / 365. Adjusting to 1000 / 850.
  float currentCorrectionFactor = 980.0 / 365.0;
  float adjustmentFactor = 1000.0 / 850.0;
  float finalCorrectionFactor = currentCorrectionFactor * adjustmentFactor;

  return (1000000.0 / interval) * 60 * 2 / 4 * finalCorrectionFactor;
}

int mapRPMToPWM(float rpm) {
  if (rpm <= 2000) {
    return 255;  // 100% PWM for RPM <= 2000
  } else if (rpm <= 4500) {
    return mapRPMToPWM_FirstRange(rpm);
  } else {
    return mapRPMToPWM_SecondRange(rpm);
  }
}

int mapRPMToPWM_FirstRange(float rpm) {
  // Map RPM to PWM duty cycle for the first range (2000 to 4500 RPM)
  float startPercentage = 100.0; // 100% PWM at 2000 RPM
  float endPercentage = 50.0;   // Ending PWM percentage at 4500 RPM

  // Calculate the PWM value based on the percentage
  float pwmPercentage = map(rpm, 2000, 4500, startPercentage, endPercentage);
  int pwmValue = (pwmPercentage / 100.0) * 255.0; // Convert percentage to 0-255 scale

  return pwmValue;
}

int mapRPMToPWM_SecondRange(float rpm) {
  // Map RPM to PWM duty cycle for the second range (4500 RPM onwards)
  float startPercentage = 50.0; // Starting PWM percentage at 4500 RPM
  float endPercentage = 40.0;   // Ending PWM percentage at 7000 RPM

  // Calculate the PWM value based on the percentage
  float pwmPercentage = map(rpm, 4500, 7000, startPercentage, endPercentage);
  int pwmValue = (pwmPercentage / 100.0) * 255.0; // Convert percentage to 0-255 scale

  return pwmValue;
}
[code]
 
holy shit i got it all working
i ran the hall sensor ground to the battery ground and not the arduino uno ground. IDIOT!(n)
now i get a nice clean signal and output
monty rips pretty solid especially when getting up and over 10 pounds

now i can tune the vvt profile some and finish up fuel map tuning too

1723226381309.png

Code:
const byte analogPin  = A0;   // Analog pin connected to the Hall sensorconst float threshold = 4.5;  // Voltage threshold for the cycleconst int numCycles   = 4;    // Number of cycles to countunsigned long cycleStartTimes[numCycles]; // Array to store start times for each cycleunsigned long cycleEndTimes[numCycles];   // Array to store end times for each cycleint cycleCount = 0;bool aboveThreshold = false;// Define output pin for PWMconst byte VVT1 = 9;const byte VVT2 = 10;void setup() {  Serial.begin(115200);  cycleStartTimes[0] = millis(); // Record the initial start time  // Initialize the PWM output pin  pinMode(VVT1, OUTPUT);  pinMode(VVT2, OUTPUT);}void loop() {  // Read the voltage from the analog pin  float voltage = analogRead(analogPin) * (5.0 / 1023.0);  // Detect the transition from below to above threshold  if (!aboveThreshold && voltage > threshold) {    aboveThreshold = true; // We're above the threshold  }  // Detect the transition from above to below threshold  if (aboveThreshold && voltage < threshold) {    aboveThreshold = false; // We're below the threshold    // Record the end time of the current cycle    cycleEndTimes[cycleCount] = millis();    cycleCount++; // Increment the cycle count    // If we have completed the required number of cycles    if (cycleCount >= numCycles) {      unsigned long totalTime = 0;      // Calculate the total time for the cycles      for (int i = 0; i < numCycles; i++) {        unsigned long cycleTime = cycleEndTimes[i] - cycleStartTimes[i];        totalTime += cycleTime;      }      // Calculate the average time per cycle      float averageTime = totalTime / (float)numCycles;      float averageTimeSeconds = averageTime / 1000.0; // Convert milliseconds to seconds      float rpm = 60.0 / averageTimeSeconds; // Calculate RPM based on average cycle time      // Divide the RPM by 2      rpm /= 2;      // Convert RPM to a whole number      int wholeRpm = (int)(rpm + 0.5); // Simple rounding without math.h      Serial.print("RPM: ");      Serial.println(wholeRpm);      int pwmValue = 0;      // Map the RPM value to the desired PWM range based on the RPM range      if (wholeRpm >= 800 && wholeRpm <= 1500) {        pwmValue = map(wholeRpm, 800, 1500, 20, 240);  // Off idle      } else if (wholeRpm > 1500 && wholeRpm <= 5000) {        pwmValue = map(wholeRpm, 1501, 5000, 240, 20); // Full RPM range      }      // Ensure the PWM value is within the range      pwmValue = constrain(pwmValue, 20, 240);      // Set the PWM output      analogWrite(VVT1, pwmValue);      analogWrite(VVT2, pwmValue);      Serial.print("PWM %");      Serial.println(pwmValue / 2.55);      // Reset for next measurement      cycleCount = 0;      cycleStartTimes[0] = millis(); // Record the new initial start time    } else {      // Record the start time for the next cycle      cycleStartTimes[cycleCount] = millis();    }  }}[code]
 
Last edited:
going to do some fuel table tuning with this profile
first ramps up off idle smoothly as the VVT sprocket has to travel to the other end of range
second is pretty much where the off idle torque starts feeling good
3rd is ramping down fast as boost and rpm are climbing quicker
lastly just runs off the minimum until revs run dry


1723231823719.png
 
so i have been kinda bumming on the lack of low end grunt on this motor over the super charged one. just thinking about it while driving.
when i built the throttle pedal assembly, i just put things in place where they worked and moved on.
it dawned on me to see how far the pedal swings and compare to the couple other cars we have here.
uh ok so....
Montero was like 5.5" swing
wife cars is crazy at about 1.5"
f250 is about 2" and my man 4x4 is about 2.5

needless to say i added some length on the leverage to pull the cable farther, faster and now the Monty has a ton of right now power. lol
took about 2" out of the swing
so many details in a ground up build
fucker rips now
i tried to stall up the motor some at a stop sign, and the ass end just started grinding over to the side
i got to break this thing like a wild horse!
 
i put a pressure gauge on my turbine to see what cosmic disaster is happening in there
its interesting that the turbo can put off like 6-8 pounds with no back pressure
but when you stomp it and that fucker gets going it will jam right up to like 25-30 psi with 10-15 on the comp side.
very interesting this i need to data log and have chat bot make a graph!

looks like the pretty small gt3076 can hold its own on a 3.0l no problem
I'm going to slap the gt3582 back on soon and check its readings
 
fuck i bet it is amazing to have a quality TIG!
the harbor freight welds good but every other utility sucks
1 pretty much scratch start on aluminum.... sometimes. sometimes no start
2 foot pedal does not have a very analog control any more. it is about 100%, 90, 50 and something below that for positions
3 cant poke any tungsten out of the cup. it will insta burn back flush and then weld nice



the casting was fairly clean but was thin and got saturated quickly
cut out the drain bung as it was only 5/8" below gasket top
now it is at the lowest @1.625?
the drain is a little low but i don't care any more like Phil Collins!




















 
Last edited:
not sure what handle lever ratio guys are using for there hand brakes but mine is not very useful!
i am thinking of adding on a small booster set up like off a Miata to get some real power over it
thoughts?

1724856944856.png
 
i put a pressure gauge on my turbine to see what cosmic disaster is happening in there
its interesting that the turbo can put off like 6-8 pounds with no back pressure
but when you stomp it and that fucker gets going it will jam right up to like 25-30 psi with 10-15 on the comp side.
very interesting this i need to data log and have chat bot make a graph!

looks like the pretty small gt3076 can hold its own on a 3.0l no problem
I'm going to slap the gt3582 back on soon and check its readings
Drive pressure will always be on the higher side of boost when under power. If you are close to 1:1 at wot through the rpm range, you have a well matched turbo to engine in that boost range. 2:1 on drive:boost is not unheard of and fine with good tuning. Pushing more than that and you are going to hurt parts and head gaskets.

Drive pressure kills more engines than boost does
 
"Drive pressure will always be on the higher side of boost when under power."

i am reading 6 or 8 psi in the manifold before any on the turbine at half-ish throttle. the turbine only really spikes at full throttle
i noticed this in my 4x4 too. i can run 10-15 psi at half throttle no trouble. 6-10 psi at full throttle will show some audible detonation
 
"Drive pressure will always be on the higher side of boost when under power."

i am reading 6 or 8 psi in the manifold before any on the turbine at half-ish throttle. the turbine only really spikes at full throttle
i noticed this in my 4x4 too. i can run 10-15 psi at half throttle no trouble. 6-10 psi at full throttle will show some audible detonation
That’s common as the engine is not needing all the air the turbo is making at the time even though turbine pressure is not registering, it’s clearly spinning up. That’s where turbo surge can occur as well.

Typically you will see signs of the wrong turbo when boost drops off up in the upper rpm range and trying to make it make more boost doesn’t help. If you watch drive pressure in that instance, it’s most likely very high and at that 2:1 ratio or higher.

Being able to watch drive pressure just means you are able to make sure things stay in check or help solve an issue. Much like an egt gauge or o2 sensor.
 
Back
Top