remap




💡 Prinsip Sederhana Remap

Sederhananya, remap adalah tindakan mengganti buku panduan di dalam otak mesin.

1. ECU Adalah Juru Masak 👨‍🍳

Bayangkan ECU adalah seorang juru masak yang bertugas membuat hidangan (tenaga mesin).

2. Map Adalah Resep 📜

Fuel Map (Waktu Injeksi) dan Ignition Timing Map (Sudut Pengapian) adalah resep yang digunakan juru masak (ECU) untuk memutuskan bahan-bahan apa yang harus dipakai.

ElemenAnalogiFungsi di Mesin
RPM & TPSKondisi Permintaan (Berapa banyak tamu dan jam berapa).Input utama dari sensor yang memberitahu ECU kondisi mesin saat ini.
Nilai Sel (Map Data)Jumlah Bahan (Berapa sendok gula, berapa ml air).Instruksi spesifik yang harus dilakukan ECU pada kondisi RPM dan TPS tertentu.

3. Prinsip Remap

Prinsip remap adalah mengubah resep agar hasilnya lebih optimal atau disesuaikan:

Tindakan RemapAnalogiHasil pada Mesin
Mengubah Fuel MapMenambah atau mengurangi takaran bahan bakar (Durasi Injeksi).Mengubah rasio udara-bahan bakar (AFR). Tujuannya, misalnya, agar campuran lebih kaya saat full throttle untuk menghindari panas berlebih.
Mengubah Timing MapMemajukan atau memundurkan waktu pengapian busi (Sudut Pengapian).Mengatur kapan busi menyala. Tujuannya adalah memastikan ledakan terjadi pada waktu yang paling ideal untuk menghasilkan torsi maksimal.

Intinya: Remap mengubah nilai-nilai di dalam Grid (Map) sehingga ketika mesin mencapai kondisi tertentu (misalnya $5000\text{ RPM}$ pada $80\% \text{ TPS}$), ECU tidak lagi menjalankan perintah pabrik, melainkan perintah yang telah Anda tuning untuk mencapai performa yang diinginkan.

Warna-warna pada Remap Grid (petak-petak data) adalah alat visual yang sangat penting dalam tuning. Warna-warna tersebut mengartikan tingkat nilai atau besaran angka dari perintah ECU di setiap kondisi RPM dan TPS.

Tujuan utama penggunaan warna (disebut Color Gradient atau Heat Map) adalah agar tuner dapat mengidentifikasi pola, perbedaan, dan area kritis di seluruh map dengan cepat, tanpa harus membaca setiap angka satu per satu.


🎨 Arti Warna pada Remap Grid (Heat Map)

Warna-warna tersebut membentuk sebuah spektrum, bergerak dari nilai rendah (dingin) ke nilai tinggi (panas).

WarnaMakna Umum (Suhu)Arti Nilai di MapArea Penggunaan Khas
Biru GelapDingin / Nilai MinimumMenunjukkan nilai yang paling rendah di seluruh map.RPM rendah dan TPS rendah (misalnya: idle dan cruising santai).
Biru Terang / CyanSejuk / Nilai Rendah-MenengahNilai berada di rentang rendah hingga menengah.Area transisi dari idle menuju low load.
KuningHangat / Nilai Menengah-TinggiNilai berada di zona performa menengah.RPM menengah (zona torsi) dengan beban yang meningkat.
OranyePanas / Nilai TinggiMenunjukkan nilai yang signifikan/tinggi.Mendekati batas tenaga, RPM tinggi.
MerahSangat Panas / Nilai MaksimumMenunjukkan nilai puncak atau maksimal yang dikirimkan ECU.Area Wide Open Throttle (WOT) atau Red Zone RPM.

🌡️ Perbedaan Makna Warna pada Map (Fuel vs. Timing)

Meskipun warnanya sama, makna fungsionalnya berbeda tergantung pada Map mana yang sedang Anda lihat:

1. Fuel Map (Durasi Injeksi dalam $\text{ms}$)

Warna di sini menunjukkan kekayaan campuran bahan bakar.

  • Merah / Oranye: Berarti durasi injeksi sangat panjang (nilai $\text{ms}$ tinggi). Ini menandakan campuran Kaya (Rich). Tuner biasanya mencari warna merah di area WOT untuk pendinginan.

  • Biru: Berarti durasi injeksi sangat singkat (nilai $\text{ms}$ rendah). Ini menandakan campuran Irit/Izin (Lean).

2. Timing Map (Sudut Pengapian dalam $^\circ\text{BTDC}$)

Warna di sini menunjukkan seberapa maju (cepat) pengapian terjadi.

  • Merah / Oranye: Berarti Sudut Pengapian sangat Maju (nilai $^\circ\text{BTDC}$ tinggi). Mesin meminta pengapian terjadi jauh sebelum Titik Mati Atas (TMA). Ini biasanya untuk mendapatkan tenaga maksimal.

  • Biru: Berarti Sudut Pengapian Sangat Mundur/Lambat (nilai $^\circ\text{BTDC}$ rendah). Biasanya terjadi di idle atau pada kondisi cruise untuk stabilitas.

Dengan melihat pola warna, Anda bisa langsung tahu: "Area merah berada di $7000-9000\text{ RPM}$ pada TPS $80\%$ ke atas. Artinya, inilah zona di mana ECU memberikan permintaan bahan bakar atau pengapian tertinggi untuk mendapatkan tenaga maksimal."

Tentu. Dua pilihan, Fuel Map (Peta Bahan Bakar) dan Ignition Timing Map (Peta Pengapian), adalah dua pilar utama yang menentukan performa, efisiensi, dan keamanan sebuah mesin.

Jika ECU adalah "otak" mesin, maka kedua map ini adalah "instruksi tertulis" yang paling penting.


1. ⛽ Fuel Map (Peta Bahan Bakar)

  • Tujuan Utama: Mengontrol jumlah bahan bakar yang disemprotkan oleh injector ke dalam ruang bakar.

  • Data yang Dikontrol: Durasi Injeksi (satuan: $\text{ms}$ atau milidetik).

    • Angka tinggi ($\text{ms}$ panjang) = Bahan Bakar Banyak (campuran Kaya/Rich).

    • Angka rendah ($\text{ms}$ pendek) = Bahan Bakar Sedikit (campuran Irit/Lean).

  • Prinsip Kerja: ECU menggunakan Fuel Map untuk mencapai rasio ideal antara udara dan bahan bakar (Air-Fuel Ratio atau AFR).

    • Saat tuning, Anda mengubah nilai di Fuel Map untuk memastikan mesin menerima jumlah bahan bakar yang tepat pada setiap kondisi RPM dan TPS.

    • Misalnya, mesin yang sudah dimodifikasi dengan knalpot free flow membutuhkan lebih banyak bahan bakar di RPM atas, sehingga Anda perlu menaikkan nilai $\text{ms}$ di area tersebut.

Analogi: Mengisi Tangki Bensin

Fuel Map menentukan seberapa lama keran bensin dibuka untuk mengisi tangki. Jika keran dibuka terlalu lama (nilai tinggi), tangki penuh (campuran kaya). Jika terlalu cepat (nilai rendah), tangki kurang isi (campuran irit).


2. 🔥 Ignition Timing Map (Peta Pengapian)

  • Tujuan Utama: Mengontrol kapan busi harus menyala (memicu pembakaran).

  • Data yang Dikontrol: Sudut Pengapian (satuan: $^\circ\text{BTDC}$ atau Degrees Before Top Dead Center).

    • Angka tinggi ($^\circ\text{BTDC}$ tinggi) = Pengapian Maju (busi menyala jauh sebelum piston mencapai titik atas).

    • Angka rendah ($^\circ\text{BTDC}$ rendah) = Pengapian Mundur (busi menyala mendekati atau setelah piston mencapai titik atas).

  • Prinsip Kerja: Pembakaran membutuhkan waktu. Pengapian harus disetel agar ledakan mencapai tekanan maksimum tepat setelah piston melewati TMA.

    • Saat tuning, Anda mencari sudut pengapian paling maju (angka tinggi) yang dapat ditoleransi mesin sebelum terjadi fenomena berbahaya yang disebut detonasi atau knocking.

    • Memajukan timing (menaikkan angka) umumnya menghasilkan tenaga dan torsi lebih besar, tetapi jika terlalu maju, mesin bisa rusak.

Analogi: Menendang Bola

Timing Map menentukan kapan Anda harus menendang bola agar bola mencapai gawang pada saat yang tepat. Jika Anda menendang terlalu cepat (Timing Maju), hasilnya kuat. Jika Anda menendang terlalu cepat sampai-sampai kaki Anda sendiri patah (Detonasi), mesin akan rusak.


Kesimpulan

Kedua map ini selalu bekerja bersamaan:

  1. Fuel Map menentukan kekuatan ledakan (energi).

  2. Timing Map menentukan kapan ledakan itu terjadi.

Seorang tuner harus menyeimbangkan keduanya. Misalnya, saat menaikkan tenaga, tuner akan memajukan Timing (Peta Pengapian) dan menambah Fuel (Peta Bahan Bakar) secara bersamaan untuk menjaga suhu mesin tetap aman dan mencegah knocking.


 <!DOCTYPE html>

<html lang="id">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Dashboard Remap ECU Motor + Grafik</title>

    

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>


    <style>

        /* --- STYLING CSS (Sedikit Dimodifikasi) --- */

        body {

            font-family: 'Arial', sans-serif;

            background-color: #f4f4f9;

            color: #333;

            margin: 0;

            padding: 20px;

        }


        .dashboard-container {

            max-width: 1200px; /* Lebar diperbesar untuk grafik */

            margin: auto;

            background: #fff;

            padding: 30px;

            border-radius: 12px;

            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);

        }


        h1 {

            color: #007bff;

            text-align: center;

            margin-bottom: 30px;

            border-bottom: 3px solid #007bff;

            padding-bottom: 10px;

        }


        .map-section {

            margin-bottom: 40px;

            padding: 15px;

            border: 1px solid #ddd;

            border-radius: 8px;

        }


        h2 {

            color: #28a745;

            border-left: 5px solid #28a745;

            padding-left: 10px;

            margin-bottom: 25px;

        }


        .grid-container {

            display: grid;

            grid-template-columns: 1fr 1fr; /* Membagi dua kolom untuk slider dan grafik */

            gap: 30px;

        }


        .parameter-grid {

            display: flex;

            flex-direction: column;

            gap: 15px;

        }


        .parameter-card {

            background-color: #e9ecef;

            padding: 15px;

            border-radius: 8px;

            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);

            transition: transform 0.2s;

        }


        .parameter-card label {

            display: block;

            font-weight: bold;

            margin-bottom: 10px;

            color: #555;

        }

        

        input[type="range"] {

            width: 100%;

            margin-bottom: 15px;

        }


        .value-display {

            font-size: 1.6em;

            color: #007bff;

            font-weight: bold;

            display: flex;

            align-items: center;

            justify-content: space-between;

        }


        .unit {

            font-size: 0.7em;

            color: #6c757d;

            font-weight: normal;

        }

        

        .chart-container {

            position: relative;

            height: 300px;

            width: 100%;

            background: white;

            padding: 10px;

            border-radius: 8px;

            box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);

        }

    </style>

</head>

<body>


    <div class="dashboard-container">

        <h1>🛠️ Dashboard Remap ECU Motor Interaktif dengan Grafik</h1>


        <div class="info-box" style="background-color: #d1ecf1; border-left: 5px solid #007bff; padding: 15px; margin-bottom: 30px; border-radius: 4px; color: #0c5460;">

            <strong>Instruksi:</strong> Geser *slider* di sisi kiri untuk melihat perubahan bentuk kurva pada **Grafik** di sisi kanan.

        </div>


        <div class="map-section">

            <h2>🔥 Ignition Timing Map (Peta Pengapian)</h2>

            <div class="grid-container">

                <div class="parameter-grid">

                    <div class="parameter-card">

                        <label>Timing Idle (0°-15°):</label>

                        <input type="range" id="timing-idle-slider" min="0" max="15" value="8.0" step="0.5" oninput="updateValue('timing-idle-slider', 'timing-idle-value', '°BTDC'); updateTimingGraph()">

                        <div class="value-display" id="timing-idle-value">8.0 <span class="unit">°BTDC</span></div>

                    </div>


                    <div class="parameter-card">

                        <label>Timing Menengah (20°-32°):</label>

                        <input type="range" id="timing-mid-slider" min="20" max="32" value="28.0" step="0.5" oninput="updateValue('timing-mid-slider', 'timing-mid-value', '°BTDC'); updateTimingGraph()">

                        <div class="value-display" id="timing-mid-value">28.0 <span class="unit">°BTDC</span></div>

                    </div>


                    <div class="parameter-card">

                        <label>Timing Puncak (28°-40°):</label>

                        <input type="range" id="timing-max-slider" min="28" max="40" value="35.0" step="0.5" oninput="updateValue('timing-max-slider', 'timing-max-value', '°BTDC'); updateTimingGraph()">

                        <div class="value-display" id="timing-max-value">35.0 <span class="unit">°BTDC</span></div>

                    </div>

                </div>

                <div class="chart-container">

                    <canvas id="timingChart"></canvas>

                </div>

            </div>

        </div>

        

        <div class="map-section">

            <h2>⛽ Fuel Map (Target AFR)</h2>

            <div class="grid-container">

                <div class="parameter-grid">

                    <div class="parameter-card">

                        <label>Target AFR (Idle - Cruise):</label>

                        <input type="range" id="afr-idle-slider" min="13.5" max="15.5" value="14.2" step="0.1" oninput="updateValue('afr-idle-slider', 'afr-idle-value', ':1'); updateAfrGraph()">

                        <div class="value-display" id="afr-idle-value">14.2 <span class="unit">:1</span></div>

                    </div>


                    <div class="parameter-card">

                        <label>Target AFR (Power/WOT):</label>

                        <input type="range" id="afr-power-slider" min="12.0" max="13.5" value="13.0" step="0.1" oninput="updateValue('afr-power-slider', 'afr-power-value', ':1'); updateAfrGraph()">

                        <div class="value-display" id="afr-power-value">13.0 <span class="unit">:1</span></div>

                    </div>

                    

                    <div class="parameter-card">

                        <label>Koreksi Durasi Injeksi Global:</label>

                        <input type="range" id="fuel-correction-slider" min="-10" max="20" value="0" step="1" oninput="updateValue('fuel-correction-slider', 'fuel-correction-value', '%')">

                        <div class="value-display" id="fuel-correction-value">0 <span class="unit">%</span></div>

                    </div>

                </div>

                <div class="chart-container">

                    <canvas id="afrChart"></canvas>

                </div>

            </div>

        </div>


    </div>


    <script>

        // --- 1. SETUP CHART.JS ---

        let timingChart, afrChart;

        

        // Data RPM untuk sumbu X

        const rpmLabels = [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000];

        

        // Inisialisasi Grafik Pengapian (Timing)

        function initTimingChart() {

            const ctx = document.getElementById('timingChart').getContext('2d');

            timingChart = new Chart(ctx, {

                type: 'line',

                data: {

                    labels: rpmLabels,

                    datasets: [{

                        label: 'Timing Pengapian (°BTDC)',

                        data: [], // Akan diisi oleh updateTimingGraph()

                        borderColor: 'rgba(255, 99, 132, 1)', // Warna Merah

                        backgroundColor: 'rgba(255, 99, 132, 0.2)',

                        fill: true,

                        tension: 0.4

                    }]

                },

                options: {

                    responsive: true,

                    maintainAspectRatio: false,

                    scales: {

                        y: {

                            beginAtZero: false,

                            title: { display: true, text: 'Timing (°BTDC)' },

                            suggestedMin: 0,

                            suggestedMax: 45

                        },

                        x: {

                            title: { display: true, text: 'RPM' }

                        }

                    }

                }

            });

        }

        

        // Inisialisasi Grafik AFR

        function initAfrChart() {

            const ctx = document.getElementById('afrChart').getContext('2d');

            afrChart = new Chart(ctx, {

                type: 'line',

                data: {

                    labels: rpmLabels,

                    datasets: [{

                        label: 'Target AFR (Rasio Udara:Bahan Bakar)',

                        data: [], // Akan diisi oleh updateAfrGraph()

                        borderColor: 'rgba(54, 162, 235, 1)', // Warna Biru

                        backgroundColor: 'rgba(54, 162, 235, 0.2)',

                        fill: true,

                        tension: 0.3

                    }]

                },

                options: {

                    responsive: true,

                    maintainAspectRatio: false,

                    scales: {

                        y: {

                            beginAtZero: false,

                            title: { display: true, text: 'AFR (:1)' },

                            suggestedMin: 12,

                            suggestedMax: 16,

                            reverse: true // AFR yang lebih kecil (Rich) di atas

                        },

                        x: {

                            title: { display: true, text: 'RPM' }

                        }

                    }

                }

            });

        }

        

        // --- 2. FUNGSI UPDATE GRAFIK ---

        

        function updateTimingGraph() {

            // Ambil nilai dari slider

            const idle = parseFloat(document.getElementById('timing-idle-slider').value);

            const mid = parseFloat(document.getElementById('timing-mid-slider').value);

            const max = parseFloat(document.getElementById('timing-max-slider').value);


            // Buat kurva pengapian (sederhana) berdasarkan 3 titik kontrol

            const newTimingData = [

                idle,                   // RPM 0 (Idle)

                idle,                   // RPM 1000

                idle + (mid - idle) / 3, // RPM 2000

                idle + (mid - idle) * 2 / 3, // RPM 3000

                mid,                    // RPM 4000 (Puncak mid-range)

                mid + (max - mid) / 4,  // RPM 5000

                mid + (max - mid) / 2,  // RPM 6000

                mid + (max - mid) * 3 / 4, // RPM 7000

                max,                    // RPM 8000 (Puncak)

                max,                    // RPM 9000

                max                     // RPM 10000

            ];


            // Update data grafik dan refresh

            timingChart.data.datasets[0].data = newTimingData;

            timingChart.update();

        }

        

        function updateAfrGraph() {

            // Ambil nilai dari slider AFR

            const afrIdle = parseFloat(document.getElementById('afr-idle-slider').value);

            const afrPower = parseFloat(document.getElementById('afr-power-slider').value);


            // Buat kurva AFR (sederhana)

            const newAfrData = [

                afrIdle, // RPM 0

                afrIdle, // RPM 1000

                (afrIdle + afrPower * 2) / 3, // AFR semakin Rich

                (afrIdle * 2 + afrPower) / 3,

                afrPower, // Mulai masuk Power AFR

                afrPower,

                afrPower,

                afrPower,

                afrPower,

                afrPower,

                afrPower

            ];


            // Update data grafik dan refresh

            afrChart.data.datasets[0].data = newAfrData;

            afrChart.update();

        }


        // --- 3. FUNGSI UPDATE NILAI SLIDER (dari kode sebelumnya) ---

        function updateValue(sliderId, displayId, unit) {

            const slider = document.getElementById(sliderId);

            let newValue = slider.value;

            const display = document.getElementById(displayId);

            let displayValue = newValue;

            let color = '#007bff'; 


            // Logika Pewarnaan Peringatan (Simulasi Resiko Remap)

            if (sliderId.includes('timing-max') && parseFloat(newValue) > 37.0) {

                color = '#dc3545'; // Merah: Resiko detonasi tinggi!

            } else if (sliderId.includes('afr-idle-slider') && parseFloat(newValue) > 15.0) {

                color = '#dc3545'; // Merah: AFR Idle terlalu kurus

            } else if (sliderId.includes('afr-power-slider') && parseFloat(newValue) > 13.5) {

                color = '#dc3545'; // Merah: AFR Power terlalu kurus

            } else if (sliderId.includes('afr-power-slider') && parseFloat(newValue) < 12.5) {

                color = '#ffc107'; // Kuning: AFR terlalu Rich

            }


            display.innerHTML = displayValue + ' <span class="unit">' + unit.trim() + '</span>';

            display.style.color = color;

        }


        // --- 4. INISIALISASI SEMUA ---

        document.addEventListener('DOMContentLoaded', () => {

            // 1. Inisialisasi Chart

            initTimingChart();

            initAfrChart();

            

            // 2. Inisialisasi Nilai Awal Slider dan Grafiknya

            updateValue('timing-idle-slider', 'timing-idle-value', '°BTDC');

            updateValue('timing-mid-slider', 'timing-mid-value', '°BTDC');

            updateValue('timing-max-slider', 'timing-max-value', '°BTDC');

            updateTimingGraph(); 


            updateValue('afr-idle-slider', 'afr-idle-value', ':1');

            updateValue('afr-power-slider', 'afr-power-value', ':1');

            updateValue('fuel-correction-slider', 'fuel-correction-value', '%');

            updateAfrGraph();

        });

    </script>


</body>

</html>

Bagus! Dengan kode HTML yang sudah dimodifikasi tersebut, Anda memiliki simulasi perangkat tuning yang canggih.

Berikut adalah panduan lengkap mengenai Cara Membaca tampilan tersebut dan Cara Mengubah Tampilannya (khususnya bagian map grid) untuk materi pengajaran Anda.


📘 Panduan Pembacaan dan Modifikasi Tampilan ECU Tuner

A. Cara Membaca Tampilan Diagnostik (Live Data Panel)

Bagian atas (Live Data Panel) meniru tampilan scanner yang menunjukkan kondisi mesin saat ini (mirip gambar 4.png).

No.ParameterCara MembacaInterpretasi (Contoh)
1.RPM MESINMenunjukkan putaran mesin saat ini.4013 RPM berarti mesin sedang di-gas (bukan idle).
2.THROTTLE POSMenunjukkan persentase bukaan katup gas (TPS).06 % berarti gas sedikit dibuka.
3.SUHU MESINSuhu pendingin mesin (ECTS).$92^\circ\text{C}$ menunjukkan mesin sudah mencapai suhu kerja normal.
4.TEGANGAN AKIVoltase sistem kelistrikan.$14.4\text{ V}$ menunjukkan sistem pengisian (kiprok) bekerja dengan baik.
5.SUDUT PENGP.Sudut Pengapian saat ini (sebelum TMA).$25^\circ\text{ BTDC}$ (Before Top Dead Center) adalah nilai yang dinamis, sesuai dengan RPM dan beban mesin.
6.WAKTU INJ.Durasi injector menyemprotkan bahan bakar (milidetik).$6.8\text{ ms}$ adalah waktu yang dibutuhkan untuk mencapai campuran AFR yang diinginkan pada RPM dan bukaan gas saat ini.
DTCKODE KERUSAKANMenunjukkan apakah ada masalah yang tersimpan di ECU.ECU OK berarti sistem error-free. Jika ada kode (misalnya DTC 46), di situlah perbaikan harus difokuskan.
Active CellKotak Putih di GridMenunjukkan sel map mana yang sedang digunakan ECU berdasarkan RPM dan TPS Live Data.Kotak ini menunjukkan lokasi ECU mengambil data Durasi Injeksi atau Sudut Pengapian saat ini.

B. Cara Merubah Tampilan Remap Grid

Bagian bawah (Interactive Remap Grid) meniru software tuning profesional (mirip gambar 23.jpg) dan berfungsi untuk mengubah data di ECU.

1. Memilih Peta (Map)

  1. Cek kotak di bagian atas Remap Grid.

  2. Gunakan dropdown Map Selector untuk memilih peta yang akan diedit:

    • Fuel Map (Durasi Inj.): Mengatur seberapa lama injector menyemprot (diukur dalam milidetik/ms). Ini memengaruhi Rasio Udara-Bahan Bakar (AFR).

    • Ignition Timing Map ($\text{}^\circ\text{BTDC}$): Mengatur kapan busi memercikkan api. Ini memengaruhi tenaga dan suhu mesin.

2. Membaca Map Grid

  • Sumbu Vertikal (Kiri): RPM (1000 hingga 10000 RPM). Ini adalah sumbu utama putaran mesin.

  • Sumbu Horizontal (Atas): TPS (Throttle Position/Bukaan Gas dalam %). Ini adalah sumbu utama beban mesin.

  • Warna Sel: Menunjukkan besaran nilai. Secara umum, Biru adalah nilai rendah (misalnya Timing Rendah), dan Merah adalah nilai tinggi/puncak (misalnya Durasi Injeksi Maksimal).

  • Nilai di Sel: Angka di setiap sel adalah nilai yang akan digunakan ECU ketika motor berada di titik RPM dan TPS tersebut.

3. Mengubah Nilai (Proses Remap)

  1. Pilih Sel: Klik pada satu atau beberapa sel yang ingin Anda ubah nilainya. Sel yang dipilih akan berwarna hijau (atau memiliki border khusus).

  2. Tentukan Delta: Masukkan nilai perubahan (Delta Value) pada kolom input di samping tombol.

    • Misalnya, masukkan 1.0.

    • Jika Anda memilih Fuel Map dan mengklik +, durasi injeksi di sel tersebut akan bertambah $1.0\text{ ms}$ (membuat campuran lebih rich).

  3. Terapkan Perubahan:

    • Tekan tombol + untuk menaikkan nilai.

    • Tekan tombol - untuk menurunkan nilai.

  4. Simpan: Dalam simulasi ini, Anda bisa mengklik tombol SIMPAN (walaupun hanya dalam konteks browser), namun dalam alat tuning nyata, ini berarti data dikirim ke ECU.

C. Cara Mengubah Tampilan Warna dan Skala

Jika Anda ingin mengubah skema warna, Anda perlu memodifikasi bagian <style> dan fungsi JavaScript getColorClass().

Item yang DiubahLokasi di KodeCara Modifikasi
Skema Warna GridCSS: .color-low hingga .color-peakUbah kode warna HEX di properti background-color pada setiap kelas.
Ambang Batas WarnaJS: function getColorClass(value, isFuel)Ubah nilai ambang batas (if (value < X) threshold = '...') untuk menentukan kapan warna berubah. (Misalnya, mengubah kapan map dianggap sebagai zona peak).
Sumbu Grid (RPM/TPS)JS: const RPM_AXIS dan const TPS_AXISUbah array ini. (Misalnya, tambahkan 11000 di RPM_AXIS jika mesin Anda berputar lebih tinggi).

Apakah Anda ingin saya memberikan contoh spesifik bagaimana mengubah Fuel Map agar lebih "basah" (richer) pada RPM 8000 dan bukaan gas 60%?

Tentu! Simulasi ini memang kompleks karena menggabungkan dua fungsi alat ECU, yaitu Diagnostik (Pembacaan Data Langsung) dan Tuning (Pengubahan Map).

Saya akan bantu menjelaskan cara membaca data kunci pada tampilan ini secara terperinci, terutama bagaimana data di panel atas (Live Data) berkaitan dengan kotak yang bergerak di Grid (Active Cell).


1. 🔍 Membaca Live Data Panel (Bagian Atas)

Panel ini adalah representasi dari data yang dibaca ECU dari sensor secara real-time, seperti alat diagnostik. Ini menunjukkan kondisi mesin saat ini.

DataDefinisi & SatuanInterpretasi DasarKeterkaitan dengan Map
RPM MESINPutaran per menit.Menunjukkan kecepatan rotasi mesin (misal: 1000 RPM = idle, 9000 RPM = full gas).Sumbu Vertikal (Y-Axis) di Map Grid.
THROTTLE POSPersentase bukaan katup gas (TPS).Menunjukkan beban atau permintaan daya oleh pengendara (misal: 5% = gas ditutup, 100% = gas penuh).Sumbu Horizontal (X-Axis) di Map Grid.
SUDUT PENGP.Sudut Pengapian ($^\circ\text{BTDC}$).Nilai ini diambil dari Grid (Timing Map). Mesin sedang bekerja dengan sudut pengapian sebesar nilai yang ditampilkan.Nilai yang berada di kotak Active Cell (ketika Anda memilih Timing Map).
WAKTU INJ.Durasi Injeksi ($\text{ms}$).Nilai ini diambil dari Grid (Fuel Map). Menunjukkan seberapa lama injector menyemprot bahan bakar.Nilai yang berada di kotak Active Cell (ketika Anda memilih Fuel Map).
DTCKode Kerusakan.Menunjukkan apakah ada masalah yang terdeteksi ECU.Digunakan untuk tujuan Diagnostik.

2. 🗺️ Memahami Interactive Remap Grid (Map)

Grid ini adalah representasi Memori ECU yang menyimpan semua perintah untuk mesin.

A. Sumbu-Sumbu Utama

  • Sumbu Vertikal (Kiri, Kolom RPM): Ini adalah nilai RPM MESIN yang terbaca dari Live Data.

  • Sumbu Horizontal (Atas, Baris TPS): Ini adalah nilai THROTTLE POS yang terbaca dari Live Data.

B. Active Cell (Kotak Putih yang Bergerak)

Ini adalah bagian paling penting untuk dipahami:

  1. Fungsi: Kotak putih yang bergerak (disebut Active Cell atau Running Cell) menunjukkan persis di mana ECU sedang membaca data di dalam memori saat ini.

  2. Cara Kerjanya:

    • Misalnya, jika Live Data RPM Anda menunjukkan 4200 RPM dan THROTTLE POS 50%.

    • Simulasi akan mencari baris RPM terdekat (yaitu 4000 RPM) dan kolom TPS terdekat (yaitu 40% atau 60%).

    • Kotak putih akan berdiam di sel yang berpotongan (misalnya, di sel 4000 RPM / 60% TPS).

  3. Keterkaitan Nilai: Nilai yang tertera di sel tersebut (misalnya, $6.8\text{ ms}$) adalah nilai yang secara real-time dikirimkan ke Live Data Panel sebagai WAKTU INJ. (jika Anda sedang memilih Fuel Map).

C. Pembacaan Nilai (Warna dan Angka)

  • Nilai (Angka di dalam Sel): Ini adalah perintah yang akan dijalankan ECU.

    • Di Fuel Map: Angka adalah Durasi Injeksi (ms). Semakin tinggi angka, semakin "basah" (kaya) campuran bahan bakar.

    • Di Timing Map: Angka adalah Sudut Pengapian ($^\circ\text{BTDC}$). Semakin tinggi angka, semakin maju (cepat) pengapian terjadi.

  • Warna Sel (Color Gradient): Warna berfungsi sebagai indikator visual cepat.

    • Biru (Low): Biasanya zona idle atau cruise ringan, nilai rendah.

    • Hijau/Kuning/Oranye (Mid): Zona di mana mesin mulai berakselerasi, nilai sedang.

    • Merah (Peak/High): Biasanya zona tenaga puncak di RPM tinggi dan Throttle penuh (100%), nilai tertinggi.


3. 📉 Membaca Irisan Map (Grafik 2D di Kanan)

Grafik ini bukan 3D Map penuh, melainkan visualisasi kurva (irisan) dari Map Grid Anda:

  • Sumbu X (Bawah): Selalu RPM AXIS (1000 - 10000 RPM).

  • Kurva (Garis Kuning): Menunjukkan bagaimana nilai (Fuel atau Timing) berubah melintasi semua RPM hanya pada satu bukaan gas (TPS terdekat) yang sedang aktif di Live Data.

  • Titik Merah (Active Point): Ini menyoroti nilai yang Active Cell sedang ambil. Titik ini bergerak ke kiri dan kanan sesuai Live RPM di panel atas.

Kesimpulan: Dengan menggabungkan pembacaan Live Data RPM/TPS (di mana mesin berada) dengan Active Cell (di mana ECU membaca data di Grid), Anda bisa melihat secara langsung map mana yang sedang memengaruhi performa mesin saat itu juga.

Apakah Anda ingin mencoba mengubah nilai di Grid (misalnya, menambahkan $1.0\text{ ms}$ pada Fuel Map di RPM 5000) dan melihat bagaimana nilai WAKTU INJ. di Live Data Panel akan berubah saat Active Cell melewatinya?

<!DOCTYPE html>

<html lang="id">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>ECU TUNER & DIAGNOSTIK V1.0 - TBSM</title>

    

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.4.0"></script>



    <style>

        /* --- STYLING UTAMA --- */

        body {

            font-family: 'Consolas', monospace; /* Font mirip tampilan terminal/scanner */

            background-color: #212121; /* Latar belakang gelap */

            color: #e0e0e0; /* Teks terang */

            margin: 0;

            padding: 20px;

        }


        .dashboard-container {

            max-width: 1300px; 

            margin: auto;

            background: #2a2a2a;

            padding: 30px;

            border-radius: 12px;

            box-shadow: 0 0 25px rgba(0, 0, 0, 0.5);

        }


        h1 {

            color: #4CAF50; /* Hijau Terang */

            text-align: center;

            margin-bottom: 30px;

            border-bottom: 3px solid #4CAF50;

            padding-bottom: 10px;

            font-size: 1.8em;

        }


        /* --- 1. LIVE DATA/DIAGNOSTIK (Mirip 4.png) --- */

        .live-data-panel {

            background-color: #1c1c1c;

            padding: 20px;

            border-radius: 8px;

            border: 2px solid #4CAF50;

            margin-bottom: 30px;

            font-size: 1.1em;

            line-height: 1.8;

            box-shadow: inset 0 0 10px rgba(76, 175, 80, 0.4);

        }


        .data-status {

            color: #4CAF50;

            font-weight: bold;

            margin-bottom: 15px;

            border-bottom: 1px dashed #4CAF50;

        }


        .data-line {

            display: flex;

            justify-content: space-between;

            padding: 5px 0;

        }


        .data-value {

            color: #FFEB3B; /* Kuning untuk nilai */

            font-weight: bold;

        }


        .dtc-box {

            background-color: #331111;

            color: #F44336; /* Merah untuk DTC */

            padding: 15px;

            border: 1px solid #F44336;

            margin-top: 15px;

            text-align: center;

            font-weight: bold;

        }

        

        /* --- 2. REMAP GRID + GRAFIK (Mirip 23.jpg) --- */

        .remap-section {

            display: grid;

            grid-template-columns: 2fr 1fr; /* Grid map lebih besar dari grafik 3D */

            gap: 20px;

            margin-top: 30px;

            padding: 20px;

            background-color: #333;

            border-radius: 8px;

        }


        .map-grid-container {

            background: #111;

            padding: 15px;

            border-radius: 5px;

            overflow-x: auto;

        }


        .tuning-controls {

            display: flex;

            gap: 10px;

            margin-bottom: 15px;

            align-items: center;

        }


        .tuning-controls select, .tuning-controls input {

            padding: 8px;

            border-radius: 4px;

            border: 1px solid #555;

            background-color: #222;

            color: #eee;

        }


        .tuning-controls button {

            cursor: pointer;

            padding: 8px 12px;

            border: none;

            border-radius: 4px;

            background-color: #007bff; /* Warna tombol default */

            color: white;

            transition: background-color 0.2s;

        }


        .tuning-controls button:hover {

            background-color: #0056b3;

        }


        table.map-grid {

            border-collapse: collapse;

            font-size: 0.8em;

            width: 100%;

        }


        .map-grid th, .map-grid td {

            border: 1px solid #444;

            padding: 4px;

            text-align: center;

            width: 40px; /* Lebar sel untuk Grid */

            height: 25px;

        }

        

        .map-grid th {

            background-color: #1a1a1a;

            color: #999;

            font-weight: normal;

        }


        .map-grid td {

            cursor: pointer;

            transition: background-color 0.1s;

        }

        

        .map-grid td.selected {

            border: 2px solid #FFEB3B !important; /* Border kuning untuk sel yang dipilih */

            box-shadow: 0 0 5px #FFEB3B;

        }


        .map-grid td.active-cell {

            border: 2px solid white; /* Sel yang aktif di tengah */

            box-shadow: 0 0 8px white;

        }

        

        /* Warna latar belakang sel berdasarkan nilai (simulasi) */

        .color-low { background-color: #0000FF; } /* Biru: Nilai rendah (e.g., Timing rendah) */

        .color-mid-low { background-color: #0080FF; }

        .color-mid { background-color: #00FFFF; } /* Cyan */

        .color-mid-high { background-color: #FFFF00; } /* Kuning */

        .color-high { background-color: #FF8000; } /* Orange */

        .color-peak { background-color: #FF0000; } /* Merah: Nilai puncak/Power */


        .graph-3d-placeholder {

            /* Menyesuaikan gaya agar chart terlihat baik */

            background-color: #1a1a1a;

            border-radius: 5px;

            padding: 20px;

            height: 400px;

        }

    </style>

</head>

<body>


    <div class="dashboard-container">

        <h1>🛠️ ECU TUNER & DIAGNOSTIK V1.0</h1>


        <div class="live-data-panel">

            <div class="data-status">STATUS: &nbsp; ✅ KONEKSI BERHASIL</div>

            

            <div class="data-line">

                <span>1. RPM MESIN:</span>

                <span class="data-value" id="live-rpm">4013 RPM</span>

            </div>

            <div class="data-line">

                <span>2. THROTTLE POS:</span>

                <span class="data-value" id="live-tps">06 %</span>

            </div>

            <div class="data-line">

                <span>3. SUHU MESIN:</span>

                <span class="data-value" id="live-temp">92 °C</span>

            </div>

            <div class="data-line">

                <span>4. TEGANGAN AKI:</span>

                <span class="data-value" id="live-volt">14.4 V</span>

            </div>

            <div class="data-line">

                <span>5. SUDUT PENGP.:</span>

                <span class="data-value" id="live-timing">25 °BTDC</span>

            </div>

            <div class="data-line">

                <span>6. WAKTU INJ.:</span>

                <span class="data-value" id="live-inj">6.8 ms</span>

            </div>


            <div class="dtc-box">

                KODE KERUSAKAN (DTC): **ECU OK. TIDAK ADA KERUSAKAN TERSIMPAN.**

            </div>

        </div>

        

        <h2 style="color: #FFEB3B; border-left-color: #FFEB3B;">⚙️ INTERACTIVE REMAP GRID</h2>


        <div class="remap-section">

            <div class="map-section">

                <div class="tuning-controls">

                    <select id="map-selector">

                        <option value="fuel">Fuel Map (Durasi Inj.)</option>

                        <option value="timing">Ignition Timing Map (°BTDC)</option>

                    </select>

                    <input type="number" id="delta-value" value="1.0" step="0.1" style="width: 80px;">

                    <label>Delta Value (Klik +):</label>

                    <button onclick="applyDelta(1)">+</button>

                    <button onclick="applyDelta(-1)">-</button>

                    <button onclick="saveMap()" style="background-color: #4CAF50; color: white; border: none; padding: 8px 15px;">SIMPAN</button>

                </div>


                <div class="map-grid-container">

                    <table class="map-grid" id="map-grid">

                        </table>

                </div>

            </div>


            <div class="graph-3d-placeholder">

                <canvas id="mapChart"></canvas>

            </div>

        </div>


    </div>


    <script>

        // Data Awal Grid

        const RPM_AXIS = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000];

        const TPS_AXIS = [5, 10, 20, 30, 40, 60, 80, 100]; // Persen TPS


        const INITIAL_FUEL_MAP = [ // Simulasi Data Durasi Injeksi (ms)

            [1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5], 

            [2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.5], 

            [2.5, 2.8, 3.1, 3.5, 4.0, 4.5, 5.0, 5.5], 

            [3.0, 3.5, 4.0, 4.5, 5.5, 6.5, 7.5, 8.0], 

            [3.5, 4.0, 4.8, 5.8, 7.0, 8.5, 9.5, 10.5], 

            [4.0, 4.5, 5.5, 7.0, 8.5, 10.0, 11.5, 12.5], 

            [4.5, 5.2, 6.5, 8.0, 9.8, 11.5, 13.0, 14.0], 

            [5.0, 6.0, 7.5, 9.0, 11.0, 13.0, 14.5, 15.5], 

            [5.5, 6.8, 8.5, 10.5, 12.5, 14.5, 16.0, 17.0], 

            [6.0, 7.5, 9.5, 11.5, 14.0, 16.0, 17.5, 18.5]  

        ];


        const INITIAL_TIMING_MAP = [ // Simulasi Data Timing Pengapian (°BTDC)

            [8, 10, 12, 14, 16, 18, 20, 22],

            [10, 12, 14, 16, 18, 20, 22, 24],

            [12, 14, 16, 18, 20, 22, 24, 26],

            [14, 16, 18, 20, 22, 24, 26, 28],

            [16, 18, 20, 22, 24, 26, 28, 30],

            [18, 20, 22, 24, 26, 28, 30, 32],

            [20, 22, 24, 26, 28, 30, 32, 34],

            [22, 24, 26, 28, 30, 32, 34, 36],

            [24, 26, 28, 30, 32, 34, 36, 38],

            [26, 28, 30, 32, 34, 36, 38, 40]

        ];


        let currentMapData = {

            fuel: JSON.parse(JSON.stringify(INITIAL_FUEL_MAP)), // Deep copy

            timing: JSON.parse(JSON.stringify(INITIAL_TIMING_MAP)) // Deep copy

        };

        let selectedCells = [];

        let currentMapType = 'fuel';

        let mapChart; // Variabel global untuk menyimpan objek Chart.js



        // --- FUNGSI UTAMA ---


        // 1. Mengisi Grid HTML

        function renderMapGrid() {

            const table = document.getElementById('map-grid');

            table.innerHTML = '';

            const data = currentMapData[currentMapType];

            const isFuel = currentMapType === 'fuel';


            // Header (TPS Axis)

            let headerHtml = '<thead><tr><th>RPM\\TPS</th>';

            TPS_AXIS.forEach(tps => {

                headerHtml += `<th>${tps}%</th>`;

            });

            headerHtml += '</tr></thead>';

            table.innerHTML += headerHtml;


            // Body (Data Cells)

            let bodyHtml = '<tbody>';

            RPM_AXIS.forEach((rpm, r) => {

                bodyHtml += `<tr><th data-row="${r}">${rpm}</th>`;

                data[r].forEach((value, c) => {

                    const colorClass = getColorClass(value, isFuel);

                    bodyHtml += `<td 

                                    data-row="${r}" 

                                    data-col="${c}" 

                                    class="${colorClass}"

                                    onclick="selectCell(this)"

                                    oncontextmenu="handleRightClick(event, this)">

                                    ${value.toFixed(isFuel ? 1 : 0)}

                                </td>`;

                });

                bodyHtml += '</tr>';

            });

            bodyHtml += '</tbody>';

            table.innerHTML += bodyHtml;


            updateLiveIndicator();

        }

        

        // Menentukan kelas warna berdasarkan nilai (simulasi)

        function getColorClass(value, isFuel) {

            let threshold;

            if (isFuel) {

                // Fuel Map (ms)

                if (value < 2.5) threshold = 'low';

                else if (value < 4.5) threshold = 'mid-low';

                else if (value < 7.0) threshold = 'mid';

                else if (value < 10.0) threshold = 'mid-high';

                else if (value < 14.0) threshold = 'high';

                else threshold = 'peak';

            } else {

                // Timing Map (°BTDC)

                if (value < 15) threshold = 'low';

                else if (value < 22) threshold = 'mid-low';

                else if (value < 28) threshold = 'mid';

                else if (value < 33) threshold = 'mid-high';

                else if (value < 38) threshold = 'high';

                else threshold = 'peak';

            }

            return `color-${threshold}`;

        }


        // 2. Logika Seleksi Sel

        function selectCell(cell) {

            const r = parseInt(cell.dataset.row);

            const c = parseInt(cell.dataset.col);

            const index = selectedCells.findIndex(sc => sc.r === r && sc.c === c);


            // Toggle selection

            if (index === -1) {

                selectedCells.push({ r, c });

                cell.classList.add('selected');

            } else {

                selectedCells.splice(index, 1);

                cell.classList.remove('selected');

            }

        }


        function clearSelection() {

            document.querySelectorAll('.map-grid td').forEach(td => {

                td.classList.remove('selected');

            });

            selectedCells = [];

        }


        function handleRightClick(event, cell) {

            event.preventDefault(); // Mencegah menu konteks default

            selectCell(cell); // Gunakan klik kanan untuk menambah/menghapus seleksi

        }

        

        // 3. Menerapkan Nilai Delta

        function applyDelta(multiplier) {

            if (selectedCells.length === 0) {

                alert("Pilih setidaknya satu sel (klik pada sel) untuk diubah nilainya.");

                return;

            }


            const deltaValue = parseFloat(document.getElementById('delta-value').value) * multiplier;

            const data = currentMapData[currentMapType];

            const isFuel = currentMapType === 'fuel';


            selectedCells.forEach(({ r, c }) => {

                let currentValue = data[r][c];

                let newValue = currentValue + deltaValue;


                // Batasan Nilai (Opsional, untuk keamanan)

                if (isFuel) {

                    newValue = Math.max(0.5, Math.min(25.0, newValue)); // Min 0.5ms, Max 25ms

                } else {

                    newValue = Math.max(0, Math.min(45, newValue)); // Min 0°BTDC, Max 45°BTDC

                }

                

                data[r][c] = parseFloat(newValue.toFixed(isFuel ? 1 : 0));

            });


            // Setelah perubahan, refresh grid dan bersihkan seleksi

            renderMapGrid();

            clearSelection();

        }


        function saveMap() {

            alert(`Map ${currentMapType.toUpperCase()} telah disimulasikan disimpan!`);

            // Dalam aplikasi nyata, ini adalah tempat data dikirim ke ECU

        }


        // 4. Update status peta saat map selector berubah

        document.getElementById('map-selector').addEventListener('change', (e) => {

            currentMapType = e.target.value;

            clearSelection();

            renderMapGrid();

            // Panggil update chart agar grafik berganti dari Fuel ke Timing

            const liveRPM = parseFloat(document.getElementById('live-rpm').textContent.replace(' RPM', ''));

            const liveTPS = parseFloat(document.getElementById('live-tps').textContent.replace(' %', ''));

            const nearestC = TPS_AXIS.findIndex(tps => Math.abs(tps - liveTPS) < Infinity);

            updateChart(nearestC, liveRPM);

        });

        

        // --- FUNGSI CHART.JS BARU ---


        function initChart() {

            const ctx = document.getElementById('mapChart').getContext('2d');

            mapChart = new Chart(ctx, {

                type: 'line',

                data: {

                    labels: RPM_AXIS, // Sumbu X adalah RPM

                    datasets: [{

                        label: `Fuel Map`,

                        data: [], 

                        borderColor: '#FFEB3B',

                        borderWidth: 3,

                        tension: 0.4,

                        fill: false

                    }]

                },

                options: {

                    responsive: true,

                    maintainAspectRatio: false,

                    plugins: {

                        legend: { display: true, labels: { color: '#e0e0e0' } },

                        title: { display: true, text: 'IRISAN MAP BERDASARKAN TPS AKTIF', color: '#e0e0e0' }

                    },

                    scales: {

                        x: { title: { display: true, text: 'RPM', color: '#999' }, ticks: { color: '#e0e0e0' }, grid: { color: '#444' } },

                        y: { title: { display: true, text: 'Durasi Inj. (ms)', color: '#999' }, ticks: { color: '#e0e0e0' }, grid: { color: '#444' } }

                    }

                }

            });

        }


        function updateChart(nearestC, liveRPM) {

            if (!mapChart || nearestC === undefined || nearestC < 0) return;

            

            const data = currentMapData[currentMapType].map(row => row[nearestC]);

            const isFuel = currentMapType === 'fuel';

            

            // Update data

            mapChart.data.datasets[0].data = data;

            

            // Update label dan unit

            mapChart.data.datasets[0].label = `${currentMapType === 'fuel' ? 'Fuel' : 'Timing'} @ TPS ${TPS_AXIS[nearestC]}%`;

            mapChart.options.scales.y.title.text = isFuel ? 'Durasi Inj. (ms)' : 'Sudut Pengp. (°)';

            

            // Cari baris RPM terdekat untuk titik aktif

            let nearestR = 0;

            let minDiffR = Infinity;

            RPM_AXIS.forEach((rpm, r) => {

                const diff = Math.abs(rpm - liveRPM);

                if (diff < minDiffR) {

                    minDiffR = diff;

                    nearestR = r;

                }

            });


            // Dataset untuk menyorot titik aktif

            const pointData = new Array(data.length).fill(null);

            if (nearestR !== -1 && data[nearestR] !== undefined) {

                pointData[nearestR] = data[nearestR];

            }


            if (mapChart.data.datasets.length === 1) {

                mapChart.data.datasets.push({

                    label: 'Titik Aktif',

                    data: pointData,

                    backgroundColor: 'white',

                    borderColor: 'white',

                    pointRadius: 6,

                    pointBorderWidth: 2,

                    pointBackgroundColor: '#F44336', // Merah

                    type: 'scatter'

                });

            } else {

                mapChart.data.datasets[1].data = pointData;

            }


            mapChart.update();

        }


        // 5. Update Indikator Sel Aktif (Simulasi Live Data)

        function updateLiveIndicator() {

            // Ambil data live (simulasi)

            const liveRPM = parseFloat(document.getElementById('live-rpm').textContent.replace(' RPM', ''));

            const liveTPS = parseFloat(document.getElementById('live-tps').textContent.replace(' %', ''));


            // Hapus indicator lama

            document.querySelectorAll('.map-grid td').forEach(td => {

                td.classList.remove('active-cell');

            });

            

            // Cari RPM terdekat (Row)

            let nearestR = 0;

            let minDiffR = Infinity;

            RPM_AXIS.forEach((rpm, r) => {

                const diff = Math.abs(rpm - liveRPM);

                if (diff < minDiffR) {

                    minDiffR = diff;

                    nearestR = r;

                }

            });


            // Cari TPS terdekat (Column)

            let nearestC = 0;

            let minDiffC = Infinity;

            TPS_AXIS.forEach((tps, c) => {

                const diff = Math.abs(tps - liveTPS);

                if (diff < minDiffC) {

                    minDiffC = diff;

                    nearestC = c;

                }

            });



            // Tandai sel yang aktif

            const activeCell = document.querySelector(`.map-grid td[data-row="${nearestR}"][data-col="${nearestC}"]`);

            if (activeCell) {

                activeCell.classList.add('active-cell');

                activeCell.scrollIntoView({ behavior: 'smooth', block: 'nearest' });

            }

            

            // Perbarui data Timing dan Injector dari map yang aktif

            if (activeCell) {

                const r = nearestR;

                const c = nearestC;

                

                const fuelValue = currentMapData.fuel[r][c].toFixed(1);

                const timingValue = currentMapData.timing[r][c].toFixed(0);


                document.getElementById('live-inj').textContent = `${fuelValue} ms`;

                document.getElementById('live-timing').textContent = `${timingValue} °BTDC`;

            }

            

            // PENTING: UPDATE CHART SETELAH MENGHITUNG NEARESTC

            updateChart(nearestC, liveRPM);

        }

        

        // 6. Simulasi Data Live (Opsional: agar terlihat dinamis)

        function simulateLiveData() {

            // Ambil data live (simulasi)

            const currentRPM = parseFloat(document.getElementById('live-rpm').textContent.replace(' RPM', ''));

            const currentTPS = parseFloat(document.getElementById('live-tps').textContent.replace(' %', ''));

            

            // Logika Perubahan (Mengubah RPM dan TPS secara acak, namun tetap dalam batas wajar)

            const newRPM = Math.round(Math.min(10000, Math.max(1000, currentRPM + (Math.random() * 800 - 400)))); // Perubahan RPM lebih besar

            const newTPS = Math.round(Math.min(100, Math.max(5, currentTPS + (Math.random() * 20 - 10)))); // Perubahan TPS lebih besar


            // Update display RPM dan TPS

            document.getElementById('live-rpm').textContent = newRPM + ' RPM';

            document.getElementById('live-tps').textContent = newTPS + ' %';

            

            // Data statis lainnya (Suhu/Voltase)

            document.getElementById('live-temp').textContent = '92 °C';

            document.getElementById('live-volt').textContent = '14.4 V';

            

            // PENTING: Panggil updateLiveIndicator agar Active Cell dan Chart juga bergerak

            updateLiveIndicator(); 

        }



        // INISIALISASI

        document.addEventListener('DOMContentLoaded', () => {

            renderMapGrid();

            initChart(); // Inisialisasi Chart

            setInterval(simulateLiveData, 500); 

            updateLiveIndicator(); 

        });

        

    </script>


</body>

</html>

Berikut analisis lengkap dari data yang tampil pada gambar ECU TUNER suryo.garage V1.0.




1. STATUS MESIN & SENSOR

Di bagian atas tampak beberapa parameter penting:

1. RPM Mesin

Terbaca: 6.050 RPM
→ Ini menunjukkan mesin sedang berada pada putaran menengah, kondisi normal untuk idle tinggi atau sedikit digas.

2. Throttle Position (TPS)

Terbaca: 40 %
→ Artinya gas terputar hampir setengah bukaan.
Tidak berada dalam posisi idle (biasanya 1–3%).

3. Suhu Mesin

Terbaca: 92 °C
→ Suhu ini normal untuk mesin injeksi yang sudah mencapai temperatur kerja.
Range aman: 80–105°C

4. Tegangan Aki

Terbaca: 14.4 V
→ Kondisi sangat baik, menandakan sistem pengisian (stator–regulator) bekerja normal.
Range normal saat mesin hidup: 13.5–14.8 V

5. Sudut Pengapian (Ignition Timing)

Terbaca: 28° BTDC
→ Artinya pengapian dimajukan 28 derajat sebelum piston mencapai TMA.
Ini termasuk normal untuk RPM 6000 pada motor injeksi.

6. Waktu Injeksi

Terbaca: 9.8 ms
Cukup besar, menandakan campuran cenderung kaya (rich) atau throttle dibuka lebar.
Normal idle: 2–3 ms
Normal RPM 6000: 7–12 ms bergantung kebutuhan map.


2. KODE KERUSAKAN (DTC)

Tertulis:

“ECU OK. TIDAK ADA KERUSAKAN TERSIMPAN.”

→ Sistem tidak menemukan error sensor atau malfungsi.
Semua komponen elektronik seperti TPS, MAP, IAT, ECT, O2 sensor (jika ada) terbaca normal.


3. REMAP GRID (Fuel & Ignition Map)

Tabel berwarna menunjukkan peta bahan bakar (fuel map) atau peta pengapian (ignition map) pada berbagai RPM & load.

Warna Grid:

  • Biru = nilai rendah (campuran lebih kurus / timing lebih kecil)

  • Kuning–Oranye = nilai sedang

  • Merah = nilai tinggi (campuran kaya / timing besar)

Ini menandakan bahwa tabel ini adalah Tuning Map Interaktif, digunakan untuk:

  • Menambah jumlah injeksi

  • Mengurangi injeksi

  • Menyesuaikan timing

  • Mengatur AFR sesuai kebutuhan performa


4. GRAFIK KURVA REMAP

Di sebelah kanan ada grafik yang menunjukkan hubungan RPM terhadap nilai map.

Terlihat:

  • Kurva naik secara linear

  • Menunjukkan peningkatan nilai injeksi / timing seiring RPM naik

  • Tidak ada lonjakan tajam → map cukup aman & stabil


📌 KESIMPULAN UTAMA

Berdasarkan data gambar:

✔ Mesin dalam kondisi normal dan sehat

✔ Tidak ada kerusakan sensor (DTC = 0)

✔ Sistem pengisian bagus (14.4 V)

✔ Suhu mesin normal (92°C)

✔ TPS terbuka sedang (40%)

✔ RPM stabil di 6050

✔ Fuel/Tuning Map tersusun rapi dan progresif

✔ Tidak ada indikasi mesin terlalu kurus atau terlalu kaya (meskipun injeksi sedikit besar karena RPM tinggi)


❗ POTENSI CATATAN UNTUK TUNING

  1. Waktu injeksi 9.8 ms cukup besar → cocok untuk mode performa.

  2. Jika motor untuk harian, bisa dikurangi sedikit pada area 4000–7000 rpm.

  3. Pastikan suhu tidak melebihi 105°C saat test dyno.

  4. Perhatikan AFR sensor (jika tersedia) untuk memastikan tidak terlalu rich.


Jika Bapak ingin:

Saya buatkan analisa versi PDF
Saya buatkan rekomendasi tuning berdasarkan motor (NMAX, Vario, R15, dll)
Saya buatkan map custom (Fuel + Ignition)
Tinggal bilang saja.

Baik, saya akan membuatkan kunci jawaban untuk Latihan Soal Angka Hilang (Tes Kecermatan) yang Anda unggah, khusus untuk Lembar 1 (Kolom 1 sampai Kolom 5).

Kunci jawaban ini didasarkan pada perbandingan angka pada setiap baris dengan angka referensi di atas setiap kolom.


🔑 Kunci Jawaban Tes Kecermatan (Angka Hilang)

Lembar 1: Kolom 1 (Angka Referensi: 6 2 5 7 1)

No.Baris AngkaHilangKunci
121576A
272651E
39863(Tidak Sesuai)C
461752B
525761E
617652B
762571E
815267D
915762B
1076512B
1121576A
1261752B
1315762B
1421576A
1521567D
1615762B
1765712B
1872651E
1961752B
2025761E
2121576A
2265712B
2372651E
2461752B
2525761E

Lembar 1: Kolom 2 (Angka Referensi: 4 5 3 9 2)

No.Baris AngkaHilangKunci
124593C
242395B
352943C
445293C
595234A
642935B
792453C
892435B
929453C
1039452E
1124593C
1295234A
1342935B
1492453C
1592453C
1642935B
1742395B
1852943C
1945293C
2095234A
2124593C
2242395B
2352943C
2445293C
2595234A

Lembar 1: Kolom 3 (Angka Referensi: 8 1 6 7 0)

No.Baris AngkaHilangKunci
12459(Tidak Sesuai)E
206871B
386107D
461078A
580716C
676810E
780167D
861780E
981607D
1001687D
1178601B
1287081B
1368017D
1401876C
1568107D
1610768A
1786107D
1806871B
1961078A
2080716C
2110768A
2286107D
2306871B
2461078A
2580716C

Lembar 1: Kolom 4 (Angka Referensi: 8 4 3 5 9)

No.Baris AngkaHilangKunci
193584B
243985D
334895D
434598A
589345D
694385D
783954B
895384B
943985D
1093558A
1139458A
1284953C
1395483C
1458934B
1598543C
1695384B
1743985D
1834895D
1934598A
2089345D
2195384B
2243985D
2334895D
2434598A
2589345D

Lembar 1: Kolom 5 (Angka Referensi: 9 3 8 5 4)

No.Baris AngkaHilangKunci
193584E
239485D
359834E
435984E
585943B
639845D
789354E
88936(Tidak Sesuai)C
998354E
1043859A
1185943B
1285943B
1339845D
1489354E
1584359A
1695384E
1739485D
1859834E
1935984E
2085943B
2195384E
2239485D
2359834E
2435984E
2585943B



Post a Comment

0 Comments