Home » Real Estate Sectors » Land Real Estate » Mineral Resources » VillaMineral Resources – Conveyor Belt Calculator

VillaMineral Resources – Conveyor Belt Calculator

VillaTerras VillaMineral

VillaTerras VillaMineral Engineering Input

Belt Settings

Material Flow

Loading Zone

Idlers

Pulleys

Motor / Drive

Environment

Engineering Output

Waiting for input...

Engineering Warnings

No warnings yet.
function exportCSV() { const vm = structuredClone(VillaMineral); const form = document.forms[‘vmForm’]; Array.from(form.elements).forEach(el => { if (el.name && el.value !== “”) { const path = el.name.split(‘.’); let ref = vm.inputs; while (path.length > 1) ref = ref[path.shift()]; const finalKey = path[0]; ref[finalKey] = isNaN(el.value) || el.type === ‘select-one’ ? (el.value === ‘true’ ? true : (el.value === ‘false’ ? false : el.value)) : parseFloat(el.value); } }); const output = vm.calc.resultSummary.call(vm); let csv = “Metric,Value\n”; for (let key in output) { csv += `”${key}”,”${output[key]}”\n`; } const blob = new Blob([csv], { type: ‘text/csv’ }); const link = document.createElement(“a”); link.href = URL.createObjectURL(blob); link.download = “VillaMineral_Results.csv”; link.click(); } function runWarnings() { const vm = structuredClone(VillaMineral); const form = document.forms[‘vmForm’]; Array.from(form.elements).forEach(el => { if (el.name && el.value !== “”) { const path = el.name.split(‘.’); let ref = vm.inputs; while (path.length > 1) ref = ref[path.shift()]; const finalKey = path[0]; ref[finalKey] = isNaN(el.value) || el.type === ‘select-one’ ? (el.value === ‘true’ ? true : (el.value === ‘false’ ? false : el.value)) : parseFloat(el.value); } }); const w = []; const idlerSpacing = vm.inputs.idler.spacing_ft; const materialDensity = vm.inputs.material.density_lbft3; const incline = vm.inputs.loading.fallAngle_deg; const plys = vm.inputs.belt.plys; const power = vm.calc.horsepowerRequired.call(vm); if (materialDensity > 100 && idlerSpacing > 4) { w.push(“Warning: Idler spacing is too far for dense materials. Consider reducing to 3 ft.”); } if (incline > 18) { w.push(“Warning: Incline exceeds recommended max for smooth belts. Consider cleated belts or reducing angle.”); } if (plys <= 3 && power > 75) { w.push(“Warning: Power demand may exceed safe tension limits for 3-ply belts. Consider 4-ply or steel cord.”); } if (w.length === 0) { w.push(“All values within standard engineering parameters.”); } document.getElementById(“warningBox”).textContent = w.join(“\n”); }

Power vs. Throughput Chart

function drawPowerTPHChart() { const vm = structuredClone(VillaMineral); const form = document.forms[‘vmForm’]; Array.from(form.elements).forEach(el => { if (el.name && el.value !== “”) { const path = el.name.split(‘.’); let ref = vm.inputs; while (path.length > 1) ref = ref[path.shift()]; const finalKey = path[0]; ref[finalKey] = isNaN(el.value) || el.type === ‘select-one’ ? (el.value === ‘true’ ? true : (el.value === ‘false’ ? false : el.value)) : parseFloat(el.value); } }); const ctx = document.getElementById(“powerChart”).getContext(“2d”); ctx.clearRect(0, 0, 1000, 300); // Axes ctx.strokeStyle = “#000”; ctx.beginPath(); ctx.moveTo(60, 10); ctx.lineTo(60, 270); ctx.lineTo(980, 270); ctx.stroke(); ctx.fillStyle = “#000”; ctx.font = “14px Arial”; ctx.fillText(“Power (HP)”, 5, 20); ctx.fillText(“TPH →”, 900, 290); // Simulate points: vary cross section from 0.5 to 4.5 ft² ctx.strokeStyle = “#0077cc”; ctx.beginPath(); for (let i = 0.5; i <= 4.5; i += 0.1) { vm.inputs.loading.crossSection_ft2 = i; const tph = vm.calc.tph.call(vm); const hp = vm.calc.horsepowerRequired.call(vm); const x = 60 + (tph / 2); // scale factor const y = 270 - (hp * 2); // scale factor if (i === 0.5) ctx.moveTo(x, y); else ctx.lineTo(x, y); } ctx.stroke(); // Draw points for (let i = 0.5; i <= 4.5; i += 0.5) { vm.inputs.loading.crossSection_ft2 = i; const tph = vm.calc.tph.call(vm); const hp = vm.calc.horsepowerRequired.call(vm); const x = 60 + (tph / 2); const y = 270 - (hp * 2); ctx.beginPath(); ctx.arc(x, y, 3, 0, 2 * Math.PI); ctx.fillStyle = "#00aa00"; ctx.fill(); ctx.fillStyle = "#000"; ctx.fillText(`${tph.toFixed(0)} TPH`, x - 15, y - 10); } } drawPowerTPHChart();

Templates

function saveTemplate() { const name = document.getElementById(“templateName”).value.trim(); if (!name) return alert(“Enter a name.”); const form = document.forms[‘vmForm’]; const vm = structuredClone(VillaMineral); Array.from(form.elements).forEach(el => { if (el.name && el.value !== “”) { const path = el.name.split(‘.’); let ref = vm.inputs; while (path.length > 1) ref = ref[path.shift()]; const finalKey = path[0]; ref[finalKey] = isNaN(el.value) || el.type === ‘select-one’ ? (el.value === ‘true’ ? true : (el.value === ‘false’ ? false : el.value)) : parseFloat(el.value); } }); const templates = JSON.parse(localStorage.getItem(“villaTemplates”) || “{}”); templates[name] = vm.inputs; localStorage.setItem(“villaTemplates”, JSON.stringify(templates)); refreshTemplateList(); } function loadTemplate() { const selected = document.getElementById(“templateSelector”).value; if (!selected) return alert(“Choose a template.”); const templates = JSON.parse(localStorage.getItem(“villaTemplates”) || “{}”); const data = templates[selected]; if (!data) return; for (const key in data) { for (const prop in data[key]) { const inputName = `${key}.${prop}`; const el = document.querySelector(`[name=”${inputName}”]`); if (el) { el.value = data[key][prop]; } } } calculateVM(); } function deleteTemplate() { const selected = document.getElementById(“templateSelector”).value; if (!selected) return alert(“Choose a template to delete.”); const templates = JSON.parse(localStorage.getItem(“villaTemplates”) || “{}”); delete templates[selected]; localStorage.setItem(“villaTemplates”, JSON.stringify(templates)); refreshTemplateList(); } function refreshTemplateList() { const templates = JSON.parse(localStorage.getItem(“villaTemplates”) || “{}”); const select = document.getElementById(“templateSelector”); select.innerHTML = ‘‘; Object.keys(templates).forEach(name => { const opt = document.createElement(“option”); opt.value = name; opt.textContent = name; select.appendChild(opt); }); } window.onload = refreshTemplateList;

Motor Sizing Assistant

Press "Run VillaMineral Engine" to get motor sizing suggestions...
function runMotorAssistant(vm) { const power = vm.calc.horsepowerRequired.call(vm); const torque = vm.calc.motorTorqueOutput.call(vm); const rpm = vm.inputs.motor.rpm / vm.inputs.motor.gearboxRatio; const plys = vm.inputs.belt.plys; let sizeClass = “Standard”; if (power > 50 && power <= 100) sizeClass = "Heavy-Duty"; if (power > 100) sizeClass = “Oversized”; let torqueComment = “OK”; if (torque > 2000 && plys <= 3) { torqueComment = "Exceeds safe belt ply limit"; } const recommendations = [ `Required Horsepower: ${power.toFixed(2)} HP`, `Motor RPM after gearbox: ${rpm.toFixed(0)} RPM`, `Torque Output: ${torque.toFixed(0)} ft-lb`, `Recommended Motor Class: ${sizeClass}`, `Torque Compatibility: ${torqueComment}`, (power > vm.inputs.motor.hp) ? “Warning: Motor undersized. Upgrade required.” : “Motor size is sufficient.” ]; document.getElementById(“motorAssistBox”).textContent = recommendations.join(‘\n’); } runMotorAssistant(vm);

Wrap Angle & Take-Up Tension

Calculated wrap angle and belt tensions will appear here...
function runWrapAndTension(vm) { const Te = vm.calc.effectiveTension.call(vm); // Effective tension const μ = 0.35; // Friction coefficient pulley-to-belt (adjustable later) const wrapAngleDeg = 210; // Typical head pulley wrap (adjustable later) const θ_rad = wrapAngleDeg * Math.PI / 180; // Use Euler’s equation: T1 = Te * e^(μθ) / (e^(μθ) – 1) const expFactor = Math.exp(μ * θ_rad); const T2 = Te / (expFactor – 1); const T1 = T2 * expFactor; const takeUpTension = T1 – T2; const out = [ `Wrap Angle: ${wrapAngleDeg}° (${θ_rad.toFixed(2)} rad)`, `Tight Side Tension (T1): ${T1.toFixed(2)} lb`, `Slack Side Tension (T2): ${T2.toFixed(2)} lb`, `Effective Tension (Te = T1 – T2): ${Te.toFixed(2)} lb`, `Required Take-Up Tension: ${takeUpTension.toFixed(2)} lb`, (takeUpTension > vm.inputs.pulleys.counterweight_lb) ? “Warning: Counterweight is too small!” : “Counterweight is sufficient.” ]; document.getElementById(“tensionBox”).textContent = out.join(“\n”); } runWrapAndTension(vm);

Surge Load Simulator

Surge results will appear here...
function runSurgeSimulator() { const surgePct = parseFloat(document.getElementById(“surgePct”).value) / 100; const surgeSeconds = parseFloat(document.getElementById(“surgeDuration”).value); const vm = structuredClone(VillaMineral); // Clone and increase cross-section temporarily const baseCrossSection = vm.inputs.loading.crossSection_ft2; vm.inputs.loading.crossSection_ft2 *= surgePct; const tphSurge = vm.calc.tph.call(vm); const hpSurge = vm.calc.horsepowerRequired.call(vm); const tensionSurge = vm.calc.effectiveTension.call(vm); const torqueSurge = vm.calc.motorTorqueOutput.call(vm); const warnings = []; if (hpSurge > vm.inputs.motor.hp * 1.1) warnings.push(“Motor may stall or trip under surge load.”); if (torqueSurge > 3000) warnings.push(“Torque exceeds typical 4-ply/5-ply belt threshold.”); if (tensionSurge > 2 * vm.inputs.pulleys.counterweight_lb) warnings.push(“Counterweight insufficient for surge tension.”); const result = [ `Surge TPH: ${tphSurge.toFixed(2)} TPH`, `Surge Power Required: ${hpSurge.toFixed(2)} HP`, `Surge Effective Tension: ${tensionSurge.toFixed(2)} lb`, `Surge Torque: ${torqueSurge.toFixed(2)} ft-lb`, `Surge Duration: ${surgeSeconds} seconds`, warnings.length ? “Warnings:\n- ” + warnings.join(“\n- “) : “All within safe surge range.” ]; document.getElementById(“surgeBox”).textContent = result.join(“\n”); // Reset model back vm.inputs.loading.crossSection_ft2 = baseCrossSection; }

Pulley Sizing Assistant

Analysis of drive and tail pulley sizing will appear here...
function runPulleySizingAssistant(vm) { const bw = vm.inputs.belt.width_in; const plys = vm.inputs.belt.plys; const speed = vm.inputs.belt.speed_fpm; const beltType = vm.inputs.belt.construction; const torque = vm.calc.motorTorqueOutput.call(vm); const faceWidth = vm.inputs.pulleys.faceWidth_in; const driveDia = vm.inputs.pulleys.driveDiameter_in; const wrapAngle = 210; // assumed default, or replace later let minDriveDia = 0; if (beltType === “Steel Cord”) minDriveDia = 24; else if (plys <= 3) minDriveDia = 16; else if (plys === 4) minDriveDia = 18; else if (plys >= 5) minDriveDia = 20; const laggingRecommended = torque > 2000 ? “Ceramic” : torque > 1200 ? “Rubber” : “Plain”; const minFaceWidth = bw + 2; // +2 inch side margin const warnings = []; if (driveDia < minDriveDia) warnings.push(`Drive pulley diameter (${driveDia}") is too small. Min recommended: ${minDriveDia}".`); if (faceWidth < minFaceWidth) warnings.push(`Face width (${faceWidth}") is too narrow. Recommended: ${minFaceWidth}".`); if (wrapAngle < 180) warnings.push(`Wrap angle too low. May reduce traction under load.`); const out = [ `Belt Width: ${bw}" | Ply Count: ${plys}`, `Recommended Min Drive Diameter: ${minDriveDia}"`, `Recommended Face Width: ${minFaceWidth}"`, `Motor Torque: ${torque.toFixed(2)} ft-lb`, `Suggested Lagging: ${laggingRecommended}`, warnings.length ? "Warnings:\n- " + warnings.join("\n- ") : "Pulley setup looks safe and balanced." ]; document.getElementById("pulleyAssistBox").textContent = out.join("\n"); } runPulleySizingAssistant(vm);

Belt Cleaner Selector

Cleaner recommendation and risk analysis will appear here...
function runCleanerSelector(vm) { const material = vm.inputs.material.type.toLowerCase(); const speed = vm.inputs.belt.speed_fpm; const width = vm.inputs.belt.width_in; const moisture = vm.inputs.material.moisture_pct; const existingCleaner = vm.inputs.environment.cleaner; const stickyMaterials = [“clay”, “soil”, “wet sand”, “fertilizer”, “ore slurry”]; const isSticky = stickyMaterials.some(m => material.includes(m)) || moisture > 8; let recommended = “None”; if (isSticky && speed > 300 && width >= 24) { recommended = “Primary + Secondary + V-Plow”; } else if (isSticky && speed > 250) { recommended = “Primary + V-Plow”; } else if (!isSticky && speed > 300) { recommended = “Primary Only”; } const warnings = []; if (recommended !== “None” && existingCleaner === “None”) { warnings.push(“Carryback risk detected. No cleaner installed.”); } if (recommended !== “None” && existingCleaner !== “None” && !recommended.includes(existingCleaner)) { warnings.push(`Installed cleaner “${existingCleaner}” may be insufficient. Consider upgrading to: ${recommended}`); } const out = [ `Material: ${material}`, `Belt Speed: ${speed} ft/min`, `Moisture: ${moisture}%`, `Recommended Cleaner Setup: ${recommended}`, `Installed Cleaner: ${existingCleaner}`, warnings.length ? “Warnings:\n- ” + warnings.join(“\n- “) : “Cleaner setup is valid and safe.” ]; document.getElementById(“cleanerBox”).textContent = out.join(“\n”); } runCleanerSelector(vm);

Transition Zone & Edge Stress

Transition analysis and belt edge stress will appear here...
function runTransitionZoneAnalysis(vm) { const bw = vm.inputs.belt.width_in; const plys = vm.inputs.belt.plys; const troughAngle = vm.inputs.idler.angle_deg; const transitionLen = vm.inputs.idler.transitionLength_ft; const tension = vm.calc.effectiveTension.call(vm); // Empirical minimum transition length formula const minTransitionLen = (bw / 12) * (troughAngle / 20) * (plys / 2.5); // Edge stress estimation: edge carries more load if transition too short const edgeTensionFactor = minTransitionLen / Math.max(transitionLen, 0.1); const edgeStress = tension * edgeTensionFactor * 0.3; const warnings = []; if (transitionLen < minTransitionLen) { warnings.push(`Transition length too short. Min recommended: ${minTransitionLen.toFixed(2)} ft.`); warnings.push(`Edge tension is excessive: ${edgeStress.toFixed(2)} lb`); } const output = [ `Belt Width: ${bw}"`, `Ply Count: ${plys}`, `Troughing Angle: ${troughAngle}°`, `Input Transition Length: ${transitionLen.toFixed(2)} ft`, `Recommended Min Transition Length: ${minTransitionLen.toFixed(2)} ft`, `Estimated Edge Stress: ${edgeStress.toFixed(2)} lb`, warnings.length ? "Warnings:\n- " + warnings.join("\n- ") : "Transition length is sufficient for safe operation." ]; document.getElementById("transitionBox").textContent = output.join("\n"); } runTransitionZoneAnalysis(vm);
wpChatIcon
wpChatIcon
Scroll to Top