Skip to main content

CODE of ANIMATION to be STUDIED (Create by CLAUDE): SISTEM ENCODER MOTOR - INTERAKTIF (PURE JS) aka Ilustrasi visual sederhana/diagram blok atau skema sensor pada motor listrik untuk menunjukkan bagaimana pengukuran kecepatan sudut dilakukan dalam sistem servo/stepper

Sistem Encoder Motor

Poros Motor
Disk Encoder (berlubang)
LED
👁️
Sensor Photo/IR
Proses Perhitungan
Pulsa ON/OFF
0
Δθ (rad)
0.000
÷
Δt (detik)
0.000
=
ω (rad/s)
0
Cara Kerja:
  • LED memancarkan cahaya ke sensor melalui disk.
  • Saat lubang lewat, cahaya terdeteksi → Pulsa ON.
  • Saat bagian padat lewat, cahaya terblokir → Pulsa OFF.
  • Setiap pulsa = perubahan sudut (Δθ).
  • Kecepatan sudut (ω) = Δθ / Δt.

SOURCE-CODE

<!--===============================-->
<!--SISTEM ENCODER MOTOR - INTERAKTIF (PURE JS)-->
<!--===============================-->

<style>
  .encoder-root {
    width: 100%;
    min-height: 100vh;
    box-sizing: border-box;
    background: linear-gradient(to bottom right, #0f172a, #1e293b);
    padding: 40px 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family: Arial, Helvetica, sans-serif;
    color: #e5e7eb;
  }

  .encoder-title {
    font-size: 32px;
    font-weight: bold;
    margin-bottom: 32px;
    text-align: center;
  }

  .encoder-label-blue {
    color: #60a5fa;
    font-weight: 600;
    margin-bottom: 8px;
  }

  .encoder-label-green {
    color: #34d399;
    font-weight: 600;
    margin-bottom: 12px;
  }

  .encoder-shaft {
    width: 8px;
    height: 70px;
    background: linear-gradient(#4b5563, #9ca3af);
    margin: 0 auto;
  }

  .encoder-disk-wrapper {
    text-align: center;
    margin-top: 20px;
  }

  .encoder-disk {
    width: 260px;
    height: 260px;
    border-radius: 50%;
    background: linear-gradient(to bottom right, #4b5563, #6b7280);
    border: 5px solid #6b7280;
    position: relative;
    box-shadow: 0 0 30px rgba(0,0,0,0.4);
    margin: 0 auto;
    transition: transform 0.016s linear;
  }

  .encoder-center {
    width: 35px;
    height: 35px;
    background: #1f2937;
    border-radius: 50%;
    border: 2px solid #4b5563;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  .encoder-hole {
    width: 22px;
    height: 22px;
    background: #020617;
    border-radius: 50%;
    border: 1px solid #111827;
    position: absolute;
    transform: translate(-50%, -50%);
  }

  .encoder-row-led-sensor {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 40px;
    margin-top: 24px;
  }

  .encoder-icon-label {
    text-align: center;
  }

  .encoder-icon {
    font-size: 28px;
    margin-bottom: 4px;
    transition: transform 0.2s;
  }

  .encoder-led-active { color:#facc15; animation:encoder-pulse 0.8s infinite; }
  .encoder-led-inactive { color:#f59e0b; }
  .encoder-sensor-active { color:#22d3ee; }
  .encoder-sensor-inactive { color:#0e7490; }

  .encoder-beam {
    width: 120px;
    height: 4px;
    background: linear-gradient(to right,#facc15,#fb923c);
    opacity: 0.6;
  }

  .encoder-button {
    margin-top: 30px;
    padding: 12px 28px;
    border-radius: 10px;
    border:none;
    font-weight:bold;
    font-size:18px;
    color:#ffffff;
    cursor:pointer;
    box-shadow:0 5px 15px rgba(0,0,0,0.4);
    transition: transform 0.1s, background 0.15s;
  }

  .encoder-button:active { transform:scale(0.96); }
  .encoder-button-start { background:#16a34a; }
  .encoder-button-start:hover { background:#15803d; }
  .encoder-button-stop { background:#dc2626; }
  .encoder-button-stop:hover { background:#b91c1c; }

  .encoder-panel {
    margin-top:40px;
    background:#1e293b;
    border:1px solid #334155;
    border-radius:12px;
    padding:25px;
    width:100%;
    max-width:550px;
    text-align:center;
  }

  .encoder-panel-title {
    font-size:22px;
    font-weight:bold;
    margin-bottom:20px;
  }

  .encoder-flow-row {
    display:flex;
    justify-content:center;
    align-items:center;
    gap:20px;
    flex-wrap:wrap;
  }

  .encoder-flow-label { font-size:13px; color:#94a3b8; }
  .encoder-flow-value {
    font-family:"Courier New", monospace;
    font-weight:bold;
    font-size:26px;
  }

  .encoder-flow-arrow { font-size:26px; color:#64748b; }

  .encoder-value-pulse { color:#34d399; }
  .encoder-value-theta { color:#60a5fa; }
  .encoder-value-dt { color:#c084fc; }
  .encoder-value-omega { color:#facc15; font-size:32px; }

  .encoder-infobox {
    margin-top:25px;
    background:rgba(30,64,175,0.4);
    border-radius:12px;
    padding:20px;
    max-width:550px;
    color:#bfdbfe;
    font-size:14px;
  }

  .encoder-infobox ul {
    margin-top:10px;
    padding-left:20px;
    line-height:1.6;
  }

  @keyframes encoder-pulse {
    0% { transform:scale(1); opacity:1; }
    50% { transform:scale(1.15); opacity:0.7; }
    100% { transform:scale(1); opacity:1; }
  }
</style>

<div class="encoder-root" id="encoder-app">
  <h1 class="encoder-title">Sistem Encoder Motor</h1>

  <!--Poros Motor-->
  <div style="margin-bottom:20px; text-align:center;">
    <div class="encoder-label-blue">Poros Motor</div>
    <div class="encoder-shaft"></div>
  </div>

  <!--Disk Encoder-->
  <div class="encoder-disk-wrapper">
    <div class="encoder-label-green">Disk Encoder (berlubang)</div>
    <div class="encoder-disk" id="encoder-disk">
      <div class="encoder-center"></div>
      <!--Lubang akan diisi via JavaScript-->
    </div>
  </div>

  <!--LED & Sensor-->
  <div class="encoder-row-led-sensor">
    <div class="encoder-icon-label">
      <div class="encoder-icon encoder-led-inactive" id="encoder-led">⚡</div>
      <div style="color:#facc15; font-weight:600;">LED</div>
    </div>

    <div class="encoder-beam"></div>

    <div class="encoder-icon-label">
      <div class="encoder-icon encoder-sensor-inactive" id="encoder-sensor">👁️</div>
      <div style="color:#22d3ee; font-weight:600;">Sensor Photo/IR</div>
    </div>
  </div>

  <!--Button-->
  <button class="encoder-button encoder-button-start" id="encoder-button">
    START Motor
  </button>

  <!--Panel Proses Perhitungan-->
  <div class="encoder-panel">
    <div class="encoder-panel-title">Proses Perhitungan</div>

    <div class="encoder-flow-row">
      <div>
        <div class="encoder-flow-label">Pulsa ON/OFF</div>
        <div class="encoder-flow-value encoder-value-pulse" id="encoder-pulse">0</div>
      </div>

      <div class="encoder-flow-arrow">→</div>

      <div>
        <div class="encoder-flow-label">Δθ (rad)</div>
        <div class="encoder-flow-value encoder-value-theta" id="encoder-dtheta">0.000</div>
      </div>

      <div class="encoder-flow-arrow">÷</div>

      <div>
        <div class="encoder-flow-label">Δt (detik)</div>
        <div class="encoder-flow-value encoder-value-dt" id="encoder-dt">0.000</div>
      </div>

      <div class="encoder-flow-arrow">=</div>

      <div>
        <div class="encoder-flow-label">ω (rad/s)</div>
        <div class="encoder-flow-value encoder-value-omega" id="encoder-omega">0</div>
      </div>
    </div>
  </div>

  <!--Info Box-->
  <div class="encoder-infobox">
    <strong>Cara Kerja:</strong>
    <ul>
      <li>LED memancarkan cahaya ke sensor melalui disk.</li>
      <li>Saat lubang lewat, cahaya terdeteksi → Pulsa ON.</li>
      <li>Saat bagian padat lewat, cahaya terblokir → Pulsa OFF.</li>
      <li>Setiap pulsa = perubahan sudut (Δθ).</li>
      <li>Kecepatan sudut (ω) = Δθ / Δt.</li>
    </ul>
  </div>

</div>

<script>
(function() {

  var holes = 12;
  var rotation = 0;
  var isRunning = false;
  var pulseCount = 0;
  var lastPulseTime = null;
  var intervalId = null;

  var diskEl = document.getElementById('encoder-disk');
  var buttonEl = document.getElementById('encoder-button');
  var pulseEl = document.getElementById('encoder-pulse');
  var dthetaEl = document.getElementById('encoder-dtheta');
  var dtEl = document.getElementById('encoder-dt');
  var omegaEl = document.getElementById('encoder-omega');
  var ledEl = document.getElementById('encoder-led');
  var sensorEl = document.getElementById('encoder-sensor');

  (function createHoles() {
    var radius = 100;
    for (var i=0; i<holes; i++) {
      var angle = (i * 360) / holes;
      var rad = (angle - 90) * Math.PI/180;
      var x = 130 + radius * Math.cos(rad);
      var y = 130 + radius * Math.sin(rad);

      var hole = document.createElement('div');
      hole.className = 'encoder-hole';
      hole.style.left = x + 'px';
      hole.style.top  = y + 'px';
      diskEl.appendChild(hole);
    }
  })();

  var deltaTheta = (2 * Math.PI) / holes;
  dthetaEl.textContent = deltaTheta.toFixed(3);

  function setRunningState(running) {
    isRunning = running;

    if (running) {
      buttonEl.textContent = 'STOP Motor';
      buttonEl.classList.remove('encoder-button-start');
      buttonEl.classList.add('encoder-button-stop');

      ledEl.classList.remove('encoder-led-inactive');
      ledEl.classList.add('encoder-led-active');

      sensorEl.classList.remove('encoder-sensor-inactive');
      sensorEl.classList.add('encoder-sensor-active');

      pulseCount = 0;
      pulseEl.textContent = '0';
      dtEl.textContent = '0.000';
      omegaEl.textContent = '0';
      lastPulseTime = null;
      rotation = 0;
      diskEl.style.transform = 'rotate(0deg)';

      startLoop();
    } else {
      buttonEl.textContent = 'START Motor';
      buttonEl.classList.remove('encoder-button-stop');
      buttonEl.classList.add('encoder-button-start');

      ledEl.classList.remove('encoder-led-active');
      ledEl.classList.add('encoder-led-inactive');

      sensorEl.classList.remove('encoder-sensor-active');
      sensorEl.classList.add('encoder-sensor-inactive');

      stopLoop();
    }
  }

  function startLoop() {
    if (intervalId !== null) return;

    intervalId = setInterval(function() {
      var prevRotation = rotation;
      rotation = (rotation + 3) % 360;
      diskEl.style.transform = 'rotate(' + rotation + 'deg)';

      var segSize = 360 / holes;
      var prevIndex = Math.floor(prevRotation / segSize);
      var newIndex  = Math.floor(rotation / segSize);

      if (prevIndex !== newIndex) {
        var now = (window.performance && performance.now)
                  ? performance.now()
                  : Date.now();

        if (lastPulseTime !== null) {
          var deltaT = (now - lastPulseTime) / 1000;
          var omega = deltaTheta / deltaT;

          dtEl.textContent = deltaT.toFixed(3);
          omegaEl.textContent = omega.toFixed(2);
        }

        lastPulseTime = now;
        pulseCount += 1;
        pulseEl.textContent = String(pulseCount);
      }

    }, 16); 
  }

  function stopLoop() {
    if (intervalId !== null) {
      clearInterval(intervalId);
      intervalId = null;
    }
  }

  buttonEl.addEventListener('click', function() {
    setRunningState(!isRunning);
  });

})();
</script>

Comments

Popular posts from this blog

[ERROR BUG]
ChatGPT+Gemini: TikTok → Blogger Embed Converter using Cloudflare/Online Server

🔄 Refresh Page ERROR BUG: The connection is blocked because it was initiated by a public page to connect to devices or servers on your local network. Planning: Revise Program CODE Code USING Javascript/Online Server Code NOT USING Javascript Sample Working Code aka Already Repaired! Temporary Solution is by Asking AI Assistant to do REPAIR CODE of (Not yet Repaired) Current Conversion Program Code-Output TikTok Archive – Embedded Preview TikTok Embed ▶ View this video on TikTok ⚠️ DISCLAIMER: INPUT URL LIMITATION This program is currently restricted to processing Full Browser URLs only. It does not support TikTok’s mobile "short-link" format (e.g., vt.tiktok.com ). Required Action: Users must open the video in a web browser and copy the expanded URL from the address bar before pasting it into this program. URL Conversion Example ❌ UNSUPPORTED: https://vt.tiktok.com/ZSaXoFyov/ ✅ REQ...

Repost! Web-Based to Android Apps Convertion (MEDIAN.CO etc.)

CONTOH HASIL Android APK "PROGRAM" SAMPLE: Youtube and Instagram EMBEDded to Blogger/Blogspot.com SOURCE CODE Click this box to download Contoh Sample SHORTCUT-APPs "precise" click to download : median.co R8: ronin1985.blogspot.com R2M: ronin-manu.blogspot.com Gw udah coba Median.co utk mengubah Website gw menjadi Aplikasi Android Keren bet!! Median.co Cekidot Software lain yg mirip! ChatGPT : If you're looking for tools similar to Median.co to convert websites into Android apps, here are some top alternatives, especially for no-code or low-code users: 🔧 Best Tools Like Median.co to Convert Website to Android Apps 1. WebViewGold Platform: Windows/macOS (Xcode/Android Studio) Key Feature: Converts any website into iOS/Android app via WebView. Pros: One-time purchase Custom splash screen, push notifications Can open external links in external browser Cons:  Requi...

REPOST: Studying WATER PUMP by ROMAN ENGINEERING

*^ Ini yg Asli Gan! Mekanisme pada Concrete Pump: Kok ky Sistem Mekanik Romawi ya?! Tapi malah bisa HANYA pake PER aka bukan "MATA BOR look a like" Mekanisme Drill yg Cost Pembuatan bikin REPOT aka harus Tool SUPER Khusus Dari Material Besi yg digunakan terlihat langsung secara kasat mata Jauh Lebih Banyak drpd Per Biasa seperti yg ditunjukkan pd Video Alternatif dgn Penggunaan PER Video dr Instagram: Source: YouTube Rome's drainage machines #history #romanempire #engineering