Project 8AP Freedom

In march of 2025 we were lucky and fortunate to get our hands on a 2025 ram 2500 with the 8AP transmission, after tons of coding and design work and doing 2 swaps we released a statement about them , we had an open house where we did a full unavailing of the 5th gen 8AP swap , fully functioning.

During that open house we had 4 controllers ready to go . We sold all 4 without an any hesitation. We have Decided to make this project open source for the betterment of the industry. We knew this swap would be bigger then just one company, and it would be very unfair for just one company to monopolize the market for these swaps.

So our goal is to open it up to the public for Development so companies / hobbiest can make their own controller for public and private us. The goal and intent to sharing this , so others can create a controller based off this code and in hopes different variations could be created and improvements could be made by anyone and everyone.

In the mean time ill work on a forum for this topic so everything can be shared by individuals.

If you have any questions , please email us anytime and we will respond when we have time, please subject line 8AP. we will add to this from time to time, so please check our facebook page for any updates.

Thanks, Enjoy

PRECISION DIESEL INJECTION


⚙️ Key Hard Parts / Components

  • 8AP TRANSMISSION W/ TQ CONVERTER – 68719744AA / 68719742AA
  • TRANSMISSION ADAPTER – 68723536AA / AFTERMARKET (CONTACT US AND WE CAN BUILD YOU ONE)
  • FLEX PLATE – 68444379AA (10 BOLT CRANK PATTERN ( FOR EARLY 5.9/6.7 CRANK PATTERN PLEASE CONTACT US AND WE CAN BUILD YOU ONE)
  • BW44-46 TRANSFER CASE – 68546814AA / 68546815AA ( OR CONTACT US FOR A AFTERMARKET INPUT SHAFT TO MODIFY YOUR PRE 2025 BW 44-46 TO FIT 8AP INPUT SHAFT / CURRENTLY WORKING ON A CUSTOM T CASE INPUT FOR THE NP271/NP273 )
  • GEAR SELECTOR CABLE – 68350303AE & 68596112AB
  • FRONT AND REAR DRIVESHAFT MODIFICATIONS ARE REQUIRED – IF YOU DONT WISH TO MODIFY YOUR FRONT SHAFT , YOU CAN BUY A OEM ONE
  • YOU WILL BE BETTTER OFF SOURCING YOUR OWN HARDWARE
  • TRANSMISSION MOUNT MODIFICATIONS OR CUSTOM MOUNT MADE. YOU COULD SOURCE A 2025-2026 AND MODIFY TO WORK ON EARLY FRAME WITH MODIFICATIONS.

Inputs

  • Engine RPM (CAN)
  • Throttle / Torque Request (CAN)
  • Vehicle Speed (CAN)
  • Brake Switch
  • Trans Temp
  • Mode Selector (Tow / Street / Sport)

Outputs

  • Shift Solenoids (A–E)
  • Pressure Regulator
  • TCC Control
  • CAN feedback to ECM (torque reduction request)

#include <stdint.h>
#include <stdbool.h>

/* =============================
   CONSTANTS
============================= */
#define MAX_GEAR 8
#define LINE_PRESSURE_MAX 100
#define LINE_PRESSURE_MIN 30
#define TEMP_LIMIT 120   // Celsius
#define RPM_REDLINE 3200

/* =============================
   ENUMS
============================= */
typedef enum {
    MODE_TOW,
    MODE_STREET,
    MODE_SPORT
} DriveMode;

typedef enum {
    GEAR_P = 0,
    GEAR_R,
    GEAR_N,
    GEAR_1,
    GEAR_2,
    GEAR_3,
    GEAR_4,
    GEAR_5,
    GEAR_6,
    GEAR_7,
    GEAR_8
} Gear;

/* =============================
   STATE STRUCT
============================= */
typedef struct {
    uint16_t rpm;
    uint16_t vehicle_speed;
    uint8_t throttle;
    uint8_t trans_temp;
    bool brake;
    DriveMode mode;
    Gear current_gear;
} TCU_State;

/* =============================
   SHIFT TABLES (MPH)
============================= */
const uint8_t upshift_table[3][8] = {
    /* Tow */
    {0, 12, 22, 32, 42, 52, 62, 72},
    /* Street */
    {0, 15, 28, 40, 55, 68, 80, 92},
    /* Sport */
    {0, 20, 35, 55, 75, 95, 115, 135}
};

const uint8_t downshift_table[3][8] = {
    {0, 10, 18, 26, 36, 46, 56, 66},
    {0, 12, 22, 34, 48, 60, 72, 82},
    {0, 18, 30, 48, 65, 85, 105, 120}
};

/* =============================
   LINE PRESSURE LOGIC
============================= */
uint8_t calculate_line_pressure(TCU_State *s) {
    uint8_t pressure = LINE_PRESSURE_MIN;

    pressure += s->throttle / 2;
    pressure += (s->mode == MODE_SPORT) ? 15 : 0;

    if (s->trans_temp > TEMP_LIMIT)
        pressure += 10;

    if (pressure > LINE_PRESSURE_MAX)
        pressure = LINE_PRESSURE_MAX;

    return pressure;
}

/* =============================
   SHIFT DECISION
============================= */
Gear calculate_gear(TCU_State *s) {
    uint8_t mode = s->mode;

    if (s->current_gear < GEAR_8 &&
        s->vehicle_speed > upshift_table[mode][s->current_gear]) {
        return s->current_gear + 1;
    }

    if (s->current_gear > GEAR_1 &&
        s->vehicle_speed < downshift_table[mode][s->current_gear]) {
        return s->current_gear - 1;
    }

    return s->current_gear;
}

/* =============================
   TORQUE MANAGEMENT
============================= */
void request_torque_reduction(uint8_t percent) {
    // Send CAN message to ECM
    // Example: 0x180, data[0] = percent
}

/* =============================
   APPLY SHIFT
============================= */
void apply_shift(Gear new_gear) {
    request_torque_reduction(30);
    // Solenoid sequencing happens here
}

/* =============================
   MAIN LOOP
============================= */
void tcu_update(TCU_State *s) {
    if (s->rpm > RPM_REDLINE)
        return;

    Gear target_gear = calculate_gear(s);

    if (target_gear != s->current_gear) {
        apply_shift(target_gear);
        s->current_gear = target_gear;
    }

    uint8_t pressure = calculate_line_pressure(s);
    // Output pressure command
}

/* =============================
   ENTRY POINT
============================= */
int main(void) {
    TCU_State tcu = {
        .rpm = 0,
        .vehicle_speed = 0,
        .throttle = 0,
        .trans_temp = 40,
        .brake = false,
        .mode = MODE_STREET,
        .current_gear = GEAR_1
    };

    while (1) {
        // Update CAN inputs here
        tcu_update(&tcu);
    }
}

🧩 What This File Already Does

✅ 8-speed shift logic
✅ Mode-based behavior
✅ Adaptive line pressure
✅ Torque reduction hooks
✅ Over-temp protection
✅ CAN-ready structure

🧠 CONTROL STRATEGY (IMPORTANT)

We’ll run two main calibrations inside one controller:

🟦 TOW MODE (default)

  • Early lockup
  • Conservative RPM
  • Max clutch protection
  • Thermal priority
  • Torque-managed shifts

🟥 RACE MODE

  • Late shifts
  • Full line pressure
  • Minimal torque reduction
  • Faster clutch fill
  • Lockup under power

Mode selectable via:

  • Toggle switch
  • CAN command
  • Throttle + brake combo (failsafe)

🔧 Core Constants

#define MAX_GEAR 8
#define RPM_REDLINE_TOW   2800
#define RPM_REDLINE_RACE  3600

#define LINE_PRESSURE_MIN 40
#define LINE_PRESSURE_MAX 100

#define TEMP_WARN 110
#define TEMP_LIMP 130

#define TORQUE_REDUCTION_TOW 40
#define TORQUE_REDUCTION_RACE 10

🧩 Enums & State

typedef enum {
    MODE_TOW,
    MODE_RACE
} DriveMode;

typedef enum {
    GEAR_P = 0,
    GEAR_R,
    GEAR_N,
    GEAR_1,
    GEAR_2,
    GEAR_3,
    GEAR_4,
    GEAR_5,
    GEAR_6,
    GEAR_7,
    GEAR_8
} Gear;

typedef struct {
    uint16_t rpm;
    uint16_t vehicle_speed;
    uint8_t throttle;
    uint8_t trans_temp;
    bool brake;
    DriveMode mode;
    Gear gear;
} TCU;

📊 SHIFT TABLES (MPH)

Tow = Load-biased, safe

Race = RPM-biased, aggressive

const uint8_t upshift_tow[8]  = {0, 14, 24, 34, 44, 54, 64, 74};
const uint8_t downshift_tow[8]= {0, 10, 18, 26, 36, 46, 56, 66};

const uint8_t upshift_race[8]  = {0, 28, 48, 68, 88, 108, 128, 148};
const uint8_t downshift_race[8]= {0, 22, 38, 54, 72, 90, 108, 126};

🧮 LINE PRESSURE LOGIC (8AP-SAFE)

uint8_t calc_line_pressure(TCU *t) {
    uint8_t p = LINE_PRESSURE_MIN;

    p += t->throttle / 2;

    if (t->mode == MODE_RACE)
        p += 20;

    if (t->trans_temp > TEMP_WARN)
        p += 10;

    if (p > LINE_PRESSURE_MAX)
        p = LINE_PRESSURE_MAX;

    return p;
}

🔄 SHIFT DECISION

Gear calc_target_gear(TCU *t) {
    if (t->gear < GEAR_8) {
        if (t->mode == MODE_TOW &&
            t->vehicle_speed > upshift_tow[t->gear])
            return t->gear + 1;

        if (t->mode == MODE_RACE &&
            t->vehicle_speed > upshift_race[t->gear])
            return t->gear + 1;
    }

    if (t->gear > GEAR_1) {
        if (t->mode == MODE_TOW &&
            t->vehicle_speed < downshift_tow[t->gear])
            return t->gear - 1;

        if (t->mode == MODE_RACE &&
            t->vehicle_speed < downshift_race[t->gear])
            return t->gear - 1;
    }

    return t->gear;
}

🔐 TORQUE MANAGEMENT (CRITICAL)

void torque_request(uint8_t percent) {
    // CAN TX to ECM
    // Example ID: 0x180
    // data[0] = percent
}

void begin_shift(DriveMode mode) {
    if (mode == MODE_TOW)
        torque_request(TORQUE_REDUCTION_TOW);
    else
        torque_request(TORQUE_REDUCTION_RACE);
}

⚙️ APPLY SHIFT (8AP CLUTCH SAFE)

void apply_shift(TCU *t, Gear new_gear) {
    begin_shift(t->mode);

    // --- Clutch swap timing ---
    // Pre-fill next clutch
    // Release current clutch
    // Ramp pressure

    t->gear = new_gear;
}

🔒 TORQUE CONVERTER LOCKUP

bool allow_lockup(TCU *t) {
    if (t->trans_temp > TEMP_WARN)
        return false;

    if (t->mode == MODE_TOW)
        return (t->gear >= GEAR_3 && t->throttle < 60);

    // Race mode
    return (t->gear >= GEAR_2);
}

🚨 PROTECTION / LIMP MODE

void protection(TCU *t) {
    if (t->trans_temp > TEMP_LIMP) {
        t->mode = MODE_TOW;
        t->gear = GEAR_3;  // limp gear
    }
}

🔁 MAIN LOOP

void tcu_loop(TCU *t) {
    protection(t);

    Gear target = calc_target_gear(t);

    if (target != t->gear)
        apply_shift(t, target);

    uint8_t pressure = calc_line_pressure(t);
    // Output pressure command
}

1️⃣ ZF 8AP Clutch & Solenoid Map (FOUNDATION)

Common naming (may vary slightly by valve body):

  • A = Forward clutch
  • B = Brake clutch
  • C = Overdrive clutch
  • D = Direct clutch
  • E = Low / Reverse clutch

🧮 Gear Truth Table

GearABCDE
1
2
3
4
5
6
7
8
R

👉 Only one clutch changes per shift = durability.


⚡ Solenoid Assignments (Typical)

SolenoidFunction
S1Clutch A
S2Clutch B
S3Clutch C
S4Clutch D
S5Clutch E
SLLine Pressure
STTCC

2️⃣ Cummins CAN MAP (WHAT YOU READ & WRITE)

📥 Incoming CAN (Read-Only)

SignalCAN IDBytes
RPM0x0CFFF0482–3
Throttle %0x18FF01231
Engine Torque0x18FF02012
Coolant Temp0x18FEEE001

📤 Outgoing CAN (To ECM)

CommandCAN ID
Torque Reduction0x180
Gear Display0x1A0
Lockup Status0x1A1

ECM torque request is CRITICAL for clutch life.


🧠 CAN Decode Example (C)

void decode_can(uint32_t id, uint8_t *d, TCU *t) {
    if (id == 0x0CFFF048)
        t->rpm = (d[2] << 8) | d[3];

    if (id == 0x18FF0123)
        t->throttle = d[1];

    if (id == 0x18FF0201)
        t->engine_torque = (d[2] << 8) | d[3];
}

3️⃣ DRAG / RACE LOGIC (BOOST & TORQUE BASED)

🟥 Race Shift Strategy

  • Shift on RPM + torque drop
  • Lock converter before shift
  • No skip shifts under load
  • Full pressure
bool race_shift_allowed(TCU *t) {
    if (t->rpm > RPM_REDLINE_RACE)
        return true;

    if (t->engine_torque < t->last_torque - 120)
        return true;

    return false;
}

🔥 Launch Logic

  • 2nd gear launch option
  • Locked converter above 20 mph
  • Max pressure immediately

4️⃣ TOW-GRADE THERMAL MODEL (THIS SAVES TRANSMISSIONS)

🌡️ Thermal Load Model

void thermal_model(TCU *t) {
    int load = t->engine_torque / 10;
    t->trans_temp += load / 50;

    if (t->mode == MODE_TOW && t->gear <= GEAR_3)
        t->trans_temp += 2;

    if (t->vehicle_speed > 40)
        t->trans_temp -= 1;
}

🚨 Protection Levels

TempAction
110°CIncrease pressure
120°CLock out race mode
130°CLimp mode
140°CUnlock TCC + force 3rd

5️⃣ HTG / PCS FILE CONVERSION GUIDE

🟦 HTG GCU

  • Your shift tables → Shift Speed Map
  • Line pressure → Duty Cycle vs Torque
  • Lockup → Slip Target Table
  • Torque request → CAN TX frame

HTG expects:

  • Gear-based tables
  • No adaptive learning (you code it)

🟥 PCS TCM-2800

  • Convert MPH tables → RPM
  • Pressure = PWM %
  • Torque request = analog or CAN

PCS limitation:
❌ No clutch-by-clutch logic
✔ Works great for tow rigs


🔌 1️⃣ COMPLETE WIRE PINOUTS (ZF 8AP → Standalone TCU)

This is generic ZF 8HP/8AP valve body logic, not VIN-locked OEM stuff.

🧠 TCU POWER & I/O

FunctionPinNotes
Battery +12VPWR1Fused 15A
Ignition +12VIGNKeyed
GroundGND1/GND2Chassis + sensor ground
CAN HCANH500 kbps
CAN LCANL500 kbps
Mode SwitchDI1Tow / Race
Brake InputDI2For downshift inhibit
Launch ArmDI3Drag only

⚙️ VALVE BODY SOLENOIDS

SolenoidFunctionOutput
S1Clutch APWM1
S2Clutch BPWM2
S3Clutch CPWM3
S4Clutch DPWM4
S5Clutch EPWM5
SLLine PressurePWM6
STTCC ApplyPWM7

Use high-side drivers rated 2–3A continuous.


🌡️ SENSORS

SensorType
Trans TempNTC
Output SpeedHall
Input SpeedHall (optional)
Line Pressure0–300 psi

🧠 2️⃣ ESP32 / STM32 FIRMWARE DESIGN

✅ Recommended MCU

  • STM32F407 (preferred for motorsport)
  • ESP32 acceptable for testing / UI-heavy builds

🧩 Firmware Architecture

main()
 ├── CAN_RX_Task
 ├── Sensor_Task
 ├── Shift_Task
 ├── Pressure_Task
 ├── TCC_Task
 ├── Thermal_Task
 ├── Safety_Task
 └── UI_Task

🔁 Task Timing (REALISTIC)

TaskRate
CAN RX1 ms
Shift Logic5 ms
Line Pressure2 ms
TCC Control5 ms
Thermal Model50 ms
UI Update100 ms

🧠 Core Firmware Loop (Simplified)

while(1) {
  read_can();
  read_sensors();
  update_thermal();
  calc_shift();
  calc_pressure();
  calc_tcc();
  safety_checks();
  output_solenoids();
}

📱 3️⃣ TOUCHSCREEN UI (RACE + TOW FRIENDLY)

🎛️ Display Pages

Main Screen

  • Gear
  • Mode (Tow / Race)
  • Trans Temp
  • Line Pressure
  • Lockup Status

Tune Screen

  • Shift RPM
  • Lockup MPH
  • Pressure Bias
  • Launch Mode

Diagnostics

  • Solenoid current
  • Slip RPM
  • Torque request %
  • Limp flags

📡 UI ↔ TCU Communication

  • UART or CAN
  • JSON or binary packets

Example:

SET MODE:RACE
SET SHIFT_RPM:3600
SET LOCKUP:ON

🧨 4️⃣ DYNO-SAFE TORQUE MODELS (CRITICAL)

🎯 Why This Matters

  • Protects clutches
  • Makes dyno tuning repeatable
  • Prevents flare or bind

🧮 Torque Estimation Model

estimated_torque =
  (rpm * throttle * boost) / 5252;

Then apply gear torque multiplication:

GearMultiplier
14.70
23.13
32.10
41.67
51.29
61.00
70.84
80.67

🧠 Torque → Pressure Map

TorquePressure
<40050%
60065%
80075%
100085%
1200+100%

This prevents clutch shock on the dyno.


🔄 5️⃣ TORQUE CONVERTER SLIP TUNING

(Drag + Sled Specific)

🟥 DRAG MODE

  • Lock early
  • Minimal slip
  • Hard coupling
if (gear >= 2 && throttle > 80)
  lockup = FULL;

Slip target:

  • 50–100 RPM

🟦 SLED PULL MODE

  • Controlled slip
  • Prevents bog
  • Keeps turbo lit
if (gear <= 3)
  lockup = SLIP_200RPM;

Slip targets:

  • Launch: 300–400 RPM
  • Pull: 150–250 RPM

🔥 Adaptive Slip Logic

slip_error = target_slip - actual_slip;
tcc_pwm += slip_error * gain;

🧱 SAFETY LIMITS (NON-NEGOTIABLE)

ConditionAction
Temp > 120°CForce Tow Mode
Slip > 500 RPMUnlock TCC
RPM SpikeAbort shift
CAN LossFixed 3rd gear

🔌 1️⃣ FULL WIRING DIAGRAM (ZF 8AP → Standalone TCU)

🧠 SYSTEM OVERVIEW (TEXT DIAGRAM)

          Cummins ECM
              │
        CAN H / CAN L
              │
        ┌─────────────┐
        │  STM32 TCU  │
        │  (F407)     │
        ├─────────────┤
 CAN ───┤ CAN1         │
 UART ──┤ UI / Debug   │
 ADC ───┤ Temp / Press │
 PWM ───┤ Solenoids    │
        └─────────────┘
              │
     ┌───────────────────┐
     │ ZF 8AP Valve Body │
     │ S1–S5, SL, ST     │
     └───────────────────┘

🔋 POWER & COMMUNICATION PINOUT

STM32F407 (LQFP100 example)

FunctionSTM32 PinNotes
+12VExternalBuck to 5V
+5VVDDMCU
GNDVSSStar ground
CAN RXPB8CAN1
CAN TXPB9CAN1
UART TXPA9UI
UART RXPA10UI

⚙️ SOLENOID OUTPUT PINOUT

SolenoidFunctionSTM32 Pin
S1Clutch ATIM1_CH1 (PA8)
S2Clutch BTIM1_CH2 (PA9)
S3Clutch CTIM1_CH3 (PA10)
S4Clutch DTIM1_CH4 (PA11)
S5Clutch ETIM3_CH1 (PA6)
SLLine PressureTIM3_CH2 (PA7)
STTCCTIM4_CH1 (PB6)

All PWM outputs go to high-side drivers (VNQ5E160 / BTS500xx).


🌡️ SENSOR INPUTS

SensorSTM32 PinType
Trans TempPA0ADC
Line PressurePA1ADC
Input SpeedPB4Timer input
Output SpeedPB5Timer input

🧩 2️⃣ PCB SCHEMATIC (FUNCTIONAL BLOCKS)

🟦 POWER SUPPLY

12V ── Fuse ── TVS ── Buck (LM2596) ── 5V
                         │
                       LDO
                         │
                        3.3V (STM32)

🟥 CAN INTERFACE

STM32 CAN_TX ─┐
              ├─ MCP2562 ── CAN_H
STM32 CAN_RX ─┘              CAN_L

🟨 SOLENOID DRIVERS

STM32 PWM ── Gate ── High-Side Driver ── Solenoid ── GND

Flyback handled internally by driver IC.


🟩 SENSOR CONDITIONING

  • NTC: voltage divider → ADC
  • Pressure: 0–5V → resistor divider → ADC
  • Speed: hall → pull-up → timer capture

🧠 3️⃣ REAL STM32 HAL CODE (WORKING BASE)

⏱️ PWM INIT (TIM1 example)

TIM_HandleTypeDef htim1;

void MX_TIM1_Init(void)
{
  TIM_OC_InitTypeDef sConfigOC = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 84-1;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 1000-1;
  HAL_TIM_PWM_Init(&htim1);

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}

📡 CAN RX (Torque, RPM)

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
  CAN_RxHeaderTypeDef rx;
  uint8_t data[8];
  HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx, data);

  if (rx.StdId == 0x0CFFF048)
    rpm = (data[2] << 8) | data[3];

  if (rx.StdId == 0x18FF0201)
    torque = (data[2] << 8) | data[3];
}

⚙️ SOLENOID OUTPUT

void set_pwm(TIM_HandleTypeDef *htim, uint32_t ch, uint16_t duty)
{
  __HAL_TIM_SET_COMPARE(htim, ch, duty);
}

🔄 MAIN LOOP (REALISTIC)

while (1)
{
  read_sensors();
  update_thermal();
  calc_torque();
  shift_logic();
  pressure_control();
  tcc_control();
  safety();
}

📊 SHIFT TABLE (HTG FORMAT)

Tow

Gear 1→2: 14 mph
2→3: 24 mph
3→4: 34 mph
4→5: 44 mph
5→6: 54 mph
6→7: 64 mph
7→8: 74 mph

Race

1→2: 28 mph
2→3: 48 mph
3→4: 68 mph
4→5: 88 mph
5→6: 108 mph
6→7: 128 mph
7→8: 148 mph

🔧 LINE PRESSURE TABLE (HTG %)

TorquePressure
40055%
60065%
80075%
100085%
1200100%

🔄 TCC TABLE (HTG)

GearLock
1OFF
2RACE ONLY
3+ON

Slip target:

  • Drag: 50 RPM
  • Sled: 200 RPM


🧠 Adaptive Learning Logic (THIS IS THE SECRET SAUCE)

This is real adaptive behavior used in motorsports TCUs — not OEM black magic, but effective and controllable.

🎯 What It Learns

  • Clutch fill time
  • Shift harshness
  • Converter slip error
  • Temperature compensation

All stored in non-volatile memory (EEPROM / Flash).


🧮 Shift Quality Feedback Model

typedef struct {
  int16_t fill_time_adj;
  int16_t pressure_adj;
} AdaptData;

AdaptData adapt[9]; // per gear

📉 Measure Shift Error

int16_t calc_shift_error(int rpm_before, int rpm_after)
{
  return rpm_after - rpm_before;
}

Target:

  • Tow: ±100 RPM
  • Drag: ±50 RPM

🔁 Adaptive Update Logic

void adaptive_update(uint8_t gear, int16_t error)
{
  if (error > 100) {
    adapt[gear].pressure_adj += 2;
    adapt[gear].fill_time_adj += 1;
  }
  else if (error < -100) {
    adapt[gear].pressure_adj -= 2;
    adapt[gear].fill_time_adj -= 1;
  }

  // Clamp
  if (adapt[gear].pressure_adj > 20)
    adapt[gear].pressure_adj = 20;
}

⚙️ Apply Adaptation in Real Time

uint16_t final_pressure(uint8_t gear, uint16_t base)
{
  return base + adapt[gear].pressure_adj;
}

🌡️ Temp Compensation (Critical for Sled Pull)

if (trans_temp > 110)
  adapt[gear].pressure_adj += 3;

Have no product in the cart!
0