Creative Technologies Lab | dokuWiki

Repository of academic adventures, experimental technology, accidental brilliance, and collaborative nerdery.

User Tools

Site Tools


extras:codikon:p5js:cnc-helper

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
extras:codikon:p5js:cnc-helper [2025/11/29 19:59] Felix Hardmood Beckextras:codikon:p5js:cnc-helper [2025/11/29 20:05] (current) Felix Hardmood Beck
Line 420: Line 420:
  
  
-===== html ===== 
  
 ===== html ===== ===== html =====
  
-<code html>+<code> 
 <!doctype html> <!doctype html>
 <html lang="de"> <html lang="de">
Line 599: Line 599:
 </div> </div>
  
-<!-- Der komplette p5.js-Sketch wird wie oben im P5.JS-Block eingefügt --> +<script> 
-<script src="sketch.js"></script>+  // CNC feed suggestion helper with adjustable bit diameter 
 +  // Includes spindle speed and chip load calculation 
 +  // Version 1.01 – angepasst auf DeWalt D26200 Drehzahlstufen 
 + 
 +  let materialSelect; 
 +  let thicknessInput; 
 +  let bitDiameterInput; 
 +  let bitTypeSelect; 
 +  let calcButton; 
 +  let resultDiv; 
 + 
 +  function applyCustomStyles() { 
 +    // Styles sind im <style>-Block definiert 
 +  } 
 + 
 +  function setup() { 
 +    applyCustomStyles(); 
 + 
 +    createCanvas(1, 1); 
 +    noLoop(); 
 +    select('canvas').style('display', 'none'); 
 + 
 +    const container = select('#calculator-container'); 
 + 
 +    const title = createDiv('CNC Feed & Chip-Load Rechner V1.01'); 
 +    title.addClass('app-title'); 
 +    title.parent(container); 
 + 
 +    const subtitle = createDiv( 
 +      'Konservative Startwerte für Hobby-CNC-Router mit DeWalt D26200. Vor Serienfertigung immer an Reststücken testen.' 
 +    ); 
 +    subtitle.addClass('app-subtitle'); 
 +    subtitle.parent(container); 
 + 
 +    const layout = createDiv(); 
 +    layout.addClass('layout'); 
 +    layout.parent(container); 
 + 
 +    const inputPanel = createDiv(); 
 +    inputPanel.addClass('panel'); 
 +    inputPanel.parent(layout); 
 + 
 +    const inputTitle = createDiv('Eingaben'); 
 +    inputTitle.addClass('panel-title'); 
 +    inputTitle.parent(inputPanel); 
 + 
 +    const matGroup = createDiv(); 
 +    matGroup.addClass('field-group'); 
 +    matGroup.parent(inputPanel); 
 + 
 +    const matLabel = createSpan('Material (Material):'); 
 +    matLabel.addClass('field-label'); 
 +    matLabel.parent(matGroup); 
 + 
 +    materialSelect = createSelect(); 
 +    materialSelect.parent(matGroup); 
 +    materialSelect.option('Birkensperrholz (Birch Plywood)'); 
 +    materialSelect.option('Kiefer (Pine)'); 
 +    materialSelect.option('Bambus (Bamboo)'); 
 +    materialSelect.option('MDF (MDF)'); 
 +    materialSelect.option('Kirschsperrholz (Cherry Plywood)'); 
 +    materialSelect.option('Harter Ahorn (Hard Maple)'); 
 +    materialSelect.option('Bubinga (Bubinga)'); 
 +    materialSelect.option('HDPE (HDPE)'); 
 +    materialSelect.option('2-Farb-HDPE (2-Color HDPE)'); 
 +    materialSelect.option('Geschäumtes PVC (Expanded PVC)'); 
 +    materialSelect.option('ABS (ABS)'); 
 +    materialSelect.option('Gussacryl (Cast Acrylic)'); 
 +    materialSelect.option('2-Farb-Acryl (2-Color Acrylic)'); 
 +    materialSelect.option('Corian (Corian)'); 
 +    materialSelect.option('Linoleum (Linoleum)'); 
 +    materialSelect.option('Leiterplattenmaterial PCB (PCB)'); 
 +    materialSelect.option('Aluminium (Aluminum)'); 
 + 
 +    const thickGroup = createDiv(); 
 +    thickGroup.addClass('field-group'); 
 +    thickGroup.parent(inputPanel); 
 + 
 +    const thickLabel = createSpan('Materialdicke [mm] (Material thickness):'); 
 +    thickLabel.addClass('field-label'); 
 +    thickLabel.parent(thickGroup); 
 + 
 +    thicknessInput = createInput(''); 
 +    thicknessInput.attribute('type', 'number'); 
 +    thicknessInput.attribute('min', '0.1'); 
 +    thicknessInput.attribute('step', '0.1'); 
 +    thicknessInput.parent(thickGroup); 
 + 
 +    const thickHint = createDiv('Typische Platten: 3 / 6 / 9 / 12 / 18 mm.'); 
 +    thickHint.addClass('hint'); 
 +    thickHint.parent(thickGroup); 
 + 
 +    const toolRow = createDiv(); 
 +    toolRow.addClass('field-row'); 
 +    toolRow.parent(inputPanel); 
 + 
 +    const bitGroup = createDiv(); 
 +    bitGroup.addClass('field-group'); 
 +    bitGroup.parent(toolRow); 
 + 
 +    const bitLabel = createSpan('Fräserdurchmesser [mm] (Bit diameter):'); 
 +    bitLabel.addClass('field-label'); 
 +    bitLabel.parent(bitGroup); 
 + 
 +    bitDiameterInput = createInput('2.5'); 
 +    bitDiameterInput.attribute('type', 'number'); 
 +    bitDiameterInput.attribute('min', '0.5'); 
 +    bitDiameterInput.attribute('step', '0.1'); 
 +    bitDiameterInput.parent(bitGroup); 
 + 
 +    const typeGroup = createDiv(); 
 +    typeGroup.addClass('field-group'); 
 +    typeGroup.parent(toolRow); 
 + 
 +    const typeLabel = createSpan('Fräser-Typ (End mill type):'); 
 +    typeLabel.addClass('field-label'); 
 +    typeLabel.parent(typeGroup); 
 + 
 +    bitTypeSelect = createSelect(); 
 +    bitTypeSelect.parent(typeGroup); 
 +    bitTypeSelect.option('Spiralnut Aufwärts (Upcut end mill)'); 
 +    bitTypeSelect.option('Gerade Schneide (Straight-cut end mill)'); 
 + 
 +    const typeHint = createDiv( 
 +      'Upcut: starker Spanabtransport, mögliche Ausrisse oben. Gerade Schneide: ruhigere Kante, weniger Spanabtransport.' 
 +    ); 
 +    typeHint.addClass('hint'); 
 +    typeHint.parent(inputPanel); 
 + 
 +    calcButton = createButton('Vorschläge berechnen (Get suggestions)'); 
 +    calcButton.parent(inputPanel); 
 +    calcButton.mousePressed(updateSettings); 
 + 
 +    const btnHint = createDiv( 
 +      'Alle Werte sind Startpunkte. Bei Geräusch, Vibration oder Brandspuren Parameter anpassen.' 
 +    ); 
 +    btnHint.addClass('hint'); 
 +    btnHint.parent(inputPanel); 
 + 
 +    const outputPanel = createDiv(); 
 +    outputPanel.addClass('panel'); 
 +    outputPanel.parent(container); 
 + 
 +    const outputTitle = createDiv('Ergebnis'); 
 +    outputTitle.addClass('panel-title'); 
 +    outputTitle.parent(outputPanel); 
 + 
 +    resultDiv = createDiv('Noch keine Berechnung durchgeführt.'); 
 +    resultDiv.parent(outputPanel); 
 + 
 +    const licenseDiv = createDiv( 
 +      'Creative Technologies Lab, FH Münster – Lizenz: Dieses Tool steht unter der Creative-Commons-Lizenz ' + 
 +        '<a href="https://creativecommons.org/licenses/by-sa/3.0/" target="_blank" rel="noopener noreferrer">CC BY-SA 3.0</a>. ' + 
 +        'Es darf kopiert, geteilt und angepasst werden, solange die Urheberschaft genannt und abgeleitete Versionen unter denselben Bedingungen weitergegeben werden; ' + 
 +        'zusätzliche Einschränkungen oder abweichende Lizenzbedingungen dürfen nicht hinzugefügt werden.' 
 +    ); 
 +    licenseDiv.addClass('license-note'); 
 +    licenseDiv.parent(container); 
 +  } 
 + 
 +  function updateSettings() { 
 +    const mat = materialSelect.value(); 
 +    const t = parseFloat(thicknessInput.value()); 
 +    const bitD = parseFloat(bitDiameterInput.value()); 
 +    const bitType = bitTypeSelect.value(); 
 + 
 +    if (isNaN(t) || t <= 0) { 
 +      resultDiv.html( 
 +        '<div class="error-message">Bitte eine gültige Materialdicke in Millimetern eingeben.</div>' 
 +      ); 
 +      return; 
 +    } 
 +    if (isNaN(bitD) || bitD <= 0) { 
 +      resultDiv.html( 
 +        '<div class="error-message">Bitte einen gültigen Fräserdurchmesser in Millimetern eingeben.</div>' 
 +      ); 
 +      return; 
 +    } 
 + 
 +    const settings = computeSettings(mat, t, bitD, bitType); 
 +    const passes = Math.ceil(t / settings.depthPerPass); 
 +    const chipLoad = settings.feedRate / (settings.spindleRPM * settings.flutes); 
 + 
 +    const summaryHtml = 
 +      '<div class="summary-row">'
 +      `<div class="summary-pill">Feed: ${Math.round(settings.feedRate)} mm/min</div>` + 
 +      `<div class="summary-pill">Plunge: ${Math.round(settings.plungeRate)} mm/min</div>` + 
 +      `<div class="summary-pill">Chip Load: ${roundTo(chipLoad, 4)} mm/Zahn</div>` + 
 +      `<div class="summary-pill">Drehzahl: ${Math.round(settings.spindleRPM)} U/min (Stufe ${settings.dial})</div>` + 
 +      `<div class="summary-pill">Depth/Pass: ${roundTo(settings.depthPerPass, 2)} mm</div>` + 
 +      `<div class="summary-pill">ca. ${passes} Durchgänge</div>` + 
 +      '</div>'; 
 + 
 +    const tableHtml = 
 +      '<table id="result-table">'
 +      '<tr>'
 +      '<th>Material</th>'
 +      '<th>Dicke [mm]</th>'
 +      '<th>Ø Bit [mm]</th>'
 +      '<th>Bit-Typ</th>'
 +      '<th>Drehzahl [U/min] (DeWalt-Stufe)</th>'
 +      '<th>Zähne</th>'
 +      '<th>Chip Load [mm]</th>'
 +      '<th>Feed [mm/min]</th>'
 +      '<th>Plunge [mm/min]</th>'
 +      '<th>Depth/Pass [mm]</th>'
 +      '<th>Plunge-Art</th>'
 +      '<th>Hinweise</th>'
 +      '</tr>'
 +      '<tr>'
 +      `<td>${mat}</td>` + 
 +      `<td>${roundTo(t, 1)}</td>` + 
 +      `<td>${roundTo(bitD, 2)}</td>` + 
 +      `<td>${bitType}</td>` + 
 +      `<td>${Math.round(settings.spindleRPM)} (Stufe ${settings.dial})</td>` + 
 +      `<td>${settings.flutes}</td>` + 
 +      `<td>${roundTo(chipLoad, 4)}</td>` + 
 +      `<td>${Math.round(settings.feedRate)}</td>` + 
 +      `<td>${Math.round(settings.plungeRate)}</td>` + 
 +      `<td>${roundTo(settings.depthPerPass, 2)}</td>` + 
 +      `<td>${settings.plungeType}</td>` + 
 +      `<td>${settings.notes}</td>` + 
 +      '</tr>'
 +      '</table>'; 
 + 
 +    resultDiv.html(summaryHtml + tableHtml); 
 +  } 
 + 
 +  // Zuordnung DeWalt D26200 Drehzahl zu Reglerstufe 1–6 
 +  function dewaltDialForRPM(rpm) { 
 +    const table = [ 
 +      { dial: 1, rpm: 16000 }, 
 +      { dial: 2, rpm: 18200 }, 
 +      { dial: 3, rpm: 20400 }, 
 +      { dial: 4, rpm: 22600 }, 
 +      { dial: 5, rpm: 24800 }, 
 +      { dial: 6, rpm: 27000 } 
 +    ]; 
 + 
 +    let best = table[0]; 
 +    let bestDiff = Math.abs(rpm - best.rpm); 
 + 
 +    for (let i = 1; i < table.length; i++) { 
 +      const d = Math.abs(rpm - table[i].rpm); 
 +      if (d < bestDiff) { 
 +        bestDiff = d; 
 +        best = table[i]; 
 +      } 
 +    } 
 +    return best.dial; 
 +  } 
 + 
 +  // Berechnung der Parameter 
 +  function computeSettings(material, thickness, bitDiameter, bitType) { 
 +    let baseFeed; 
 +    let plunge; 
 +    let depthFactor; 
 +    let spindleRPM; 
 +    let flutes; 
 +    let plungeType = 'Rampe 5° (Ramp 5°)'; 
 +    let notes; 
 + 
 +    switch (material) { 
 +      case 'Birkensperrholz (Birch Plywood)': 
 +      case 'Bambus (Bamboo)': 
 +      case 'MDF (MDF)': 
 +      case 'Kirschsperrholz (Cherry Plywood)': 
 +        baseFeed = 1800; 
 +        plunge = 600; 
 +        depthFactor = 0.32; 
 +        spindleRPM = 16000; // DeWalt Stufe 1 
 +        flutes = 2; 
 +        notes = 
 +          'Standard-Holzeinstellung. Empfohlene Fräser: 2-Schneider-Spiralnut, ggf. Downcut oder Kompressionsfräser.'; 
 +        break; 
 +      case 'Kiefer (Pine)': 
 +        baseFeed = 1900; 
 +        plunge = 650; 
 +        depthFactor = 0.32; 
 +        spindleRPM = 16000; // weiches Holz, Stufe 1 ausreichend 
 +        flutes = 2; 
 +        notes = 'Weiches Nadelholz; etwas höhere Vorschubgeschwindigkeit möglich.'; 
 +        break; 
 +      case 'Harter Ahorn (Hard Maple)': 
 +      case 'Bubinga (Bubinga)': 
 +        baseFeed = 1300; 
 +        plunge = 400; 
 +        depthFactor = 0.24; 
 +        spindleRPM = 16000; // konservativ, Stufe 1 
 +        flutes = 2; 
 +        notes = 
 +          'Hartes Holz; reduzierte Zustelltiefe. Empfohlene Fräser: sehr scharfe 2-Schneider-Spiralnut.'; 
 +        break; 
 +      case 'HDPE (HDPE)': 
 +      case '2-Farb-HDPE (2-Color HDPE)': 
 +      case 'Geschäumtes PVC (Expanded PVC)': 
 +      case 'ABS (ABS)': 
 +        baseFeed = 2200; 
 +        plunge = 700; 
 +        depthFactor = 0.32; 
 +        spindleRPM = 18000; // nahe Stufe 2 (≈18200 U/min) 
 +        flutes = 2; 
 +        notes = 
 +          'Weicher Kunststoff; höherer Feed hilft gegen Schmelzen. Empfohlen: polierte Spiralnut, 1–2 Schneiden.'; 
 +        break; 
 +      case 'Gussacryl (Cast Acrylic)': 
 +      case '2-Farb-Acryl (2-Color Acrylic)': 
 +        baseFeed = 1200; 
 +        plunge = 400; 
 +        depthFactor = 0.24; 
 +        spindleRPM = 16000; // eher niedrige Drehzahl für Acryl 
 +        flutes = 1; 
 +        notes = 
 +          'Sprödes Acryl; konservative Zustelltiefe. Einzahn-Spiralnut mit polierten Schneiden ist oft vorteilhaft.'; 
 +        break; 
 +      case 'Corian (Corian)': 
 +        baseFeed = 1200; 
 +        plunge = 400; 
 +        depthFactor = 0.24; 
 +        spindleRPM = 16000; 
 +        flutes = 2; 
 +        notes = 'Dichter Mineralwerkstoff; ähnlich hartem Holz, gute Absaugung notwendig.'; 
 +        break; 
 +      case 'Linoleum (Linoleum)': 
 +        baseFeed = 1900; 
 +        plunge = 650; 
 +        depthFactor = 0.4; 
 +        spindleRPM = 16000; 
 +        flutes = 2; 
 +        notes = 'Weiches Material; größere Zustelltiefe möglich. Trägerschicht beachten.'; 
 +        break; 
 +      case 'Leiterplattenmaterial PCB (PCB)': 
 +        baseFeed = 800; 
 +        plunge = 250; 
 +        depthFactor = 0.12; 
 +        spindleRPM = 18000; // kleine Einzahnwerkzeuge, höhere Drehzahl 
 +        flutes = 1; 
 +        notes = 
 +          'Isolationsfräsen; sehr flache Zustellung. Häufig kleine Einzahnwerkzeuge (0,8–1,0 mm) mit V- oder Geradegeometrie.'; 
 +        break; 
 +      case 'Aluminium (Aluminum)': 
 +        baseFeed = 700; 
 +        plunge = 220; 
 +        depthFactor = 0.1; 
 +        spindleRPM = 16000; // auf DeWalt-Minimum angehoben (Stufe 1) 
 +        flutes = 2; 
 +        notes = 
 +          'Metallbearbeitung; geringe Zustelltiefe, gute Spanntechnik und ggf. Schmierung notwendig. Empfohlen: 1–2-Schneider-Aluminiumfräser (Upcut).'; 
 +        break; 
 +      default: 
 +        baseFeed = 1500; 
 +        plunge = 500; 
 +        depthFactor = 0.28; 
 +        spindleRPM = 16000; 
 +        flutes = 2; 
 +        notes = 'Generische Einstellung; bitte an Reststück prüfen.'; 
 +        break; 
 +    } 
 + 
 +    const refDiameter = 2.5; 
 +    const feedScale = Math.sqrt(bitDiameter / refDiameter); 
 +    let feed = baseFeed * feedScale; 
 + 
 +    let depth = depthFactor * bitDiameter; 
 +    depth = constrain(depth, 0.15, bitDiameter * 0.5); 
 + 
 +    if (thickness < 4) { 
 +      feed *= 1.05; 
 +      notes += ' Dünnes Material: Feed leicht erhöht.'; 
 +    } else if (thickness > 12 && thickness <= 20) { 
 +      feed *= 0.9; 
 +      notes += ' Dickes Material: Feed leicht reduziert.'; 
 +    } else if (thickness > 20) { 
 +      feed *= 0.85; 
 +      notes += 
 +        ' Sehr dickes Material: eher in mehreren Stufen bearbeiten, ggf. von beiden Seiten.'; 
 +    } 
 + 
 +    if (bitType === 'Spiralnut Aufwärts (Upcut end mill)') { 
 +      notes += ' Gewählter Fräser: Upcut; sehr guter Spanabtransport, mögliche Ausrisse oben.'; 
 +    } else if (bitType === 'Gerade Schneide (Straight-cut end mill)') { 
 +      notes += 
 +        ' Gewählter Fräser: gerade Schneide; gute Kantenqualität in Holz/Kunststoff, Spanabtransport geringer.'; 
 +    } 
 + 
 +    if (bitDiameter < 1.0 && flutes > 1) { 
 +      flutes = 1; 
 +      notes = 
 +        'Hinweis: Für Fräser unter 1.0 mm wird die Zahnzahl vorsorglich auf 1 gesetzt. ' + 
 +        notes; 
 +    } 
 + 
 +    const dial = dewaltDialForRPM(spindleRPM); 
 + 
 +    return { 
 +      feedRate: feed, 
 +      plungeRate: plunge, 
 +      depthPerPass: depth, 
 +      spindleRPM: spindleRPM, 
 +      flutes: flutes, 
 +      plungeType: plungeType, 
 +      notes: notes, 
 +      dial: dial 
 +    }; 
 +  } 
 + 
 +  function roundTo(value, decimals) { 
 +    return Number(value.toFixed(decimals)); 
 +  } 
 +</script>
  
 </body> </body>
 </html> </html>
 </code> </code>
/var/www/vhosts/ct-lab.info/wiki.ct-lab.info/data/attic/extras/codikon/p5js/cnc-helper.1764446371.txt.gz · Last modified: by Felix Hardmood Beck