603 lines
27 KiB
JavaScript
603 lines
27 KiB
JavaScript
import React, { useState } from 'react';
|
||
import { Download, Settings, Maximize2, Move, Box } from 'lucide-react';
|
||
|
||
export default function PrinterCalibration() {
|
||
const [activeTab, setActiveTab] = useState('x-axis');
|
||
const [settings, setSettings] = useState({
|
||
bedTemp: 60,
|
||
nozzleTemp: 200,
|
||
bedSize: { x: 220, y: 220, z: 250 },
|
||
nozzleDiameter: 0.4,
|
||
filamentDiameter: 1.75,
|
||
});
|
||
|
||
const [xAxisConfig, setXAxisConfig] = useState({
|
||
distance: 100,
|
||
steps: 80,
|
||
measured: 0,
|
||
});
|
||
|
||
const [yAxisConfig, setYAxisConfig] = useState({
|
||
distance: 100,
|
||
steps: 80,
|
||
measured: 0,
|
||
});
|
||
|
||
const [zAxisConfig, setZAxisConfig] = useState({
|
||
distance: 10,
|
||
steps: 400,
|
||
measured: 0,
|
||
});
|
||
|
||
const [extruderConfig, setExtruderConfig] = useState({
|
||
distance: 100,
|
||
steps: 93,
|
||
measured: 0,
|
||
});
|
||
|
||
const [skewConfig, setSkewConfig] = useState({
|
||
ac: 141.4,
|
||
bd: 141.4,
|
||
ad: 141.4,
|
||
});
|
||
|
||
const calculateXSteps = () => {
|
||
if (xAxisConfig.measured > 0) {
|
||
const newSteps = (xAxisConfig.distance / xAxisConfig.measured) * xAxisConfig.steps;
|
||
return newSteps.toFixed(2);
|
||
}
|
||
return xAxisConfig.steps;
|
||
};
|
||
|
||
const calculateYSteps = () => {
|
||
if (yAxisConfig.measured > 0) {
|
||
const newSteps = (yAxisConfig.distance / yAxisConfig.measured) * yAxisConfig.steps;
|
||
return newSteps.toFixed(2);
|
||
}
|
||
return yAxisConfig.steps;
|
||
};
|
||
|
||
const calculateZSteps = () => {
|
||
if (zAxisConfig.measured > 0) {
|
||
const newSteps = (zAxisConfig.distance / zAxisConfig.measured) * zAxisConfig.steps;
|
||
return newSteps.toFixed(2);
|
||
}
|
||
return zAxisConfig.steps;
|
||
};
|
||
|
||
const calculateESteps = () => {
|
||
if (extruderConfig.measured > 0) {
|
||
const newSteps = (extruderConfig.distance / extruderConfig.measured) * extruderConfig.steps;
|
||
return newSteps.toFixed(2);
|
||
}
|
||
return extruderConfig.steps;
|
||
};
|
||
|
||
const calculateSkew = () => {
|
||
const ac = parseFloat(skewConfig.ac);
|
||
const bd = parseFloat(skewConfig.bd);
|
||
const ad = parseFloat(skewConfig.ad);
|
||
|
||
if (ac > 0 && bd > 0 && ad > 0) {
|
||
const xy_skew = Math.atan2(ac - 141.4, 100) * (180 / Math.PI);
|
||
const xz_skew = Math.atan2(bd - 141.4, 100) * (180 / Math.PI);
|
||
const yz_skew = Math.atan2(ad - 141.4, 100) * (180 / Math.PI);
|
||
|
||
return {
|
||
xy: xy_skew.toFixed(4),
|
||
xz: xz_skew.toFixed(4),
|
||
yz: yz_skew.toFixed(4)
|
||
};
|
||
}
|
||
return { xy: '0.0000', xz: '0.0000', yz: '0.0000' };
|
||
};
|
||
|
||
const generateGCode = () => {
|
||
let gcode = '; 3D Yazıcı Kalibrasyon G-Code\n';
|
||
gcode += '; Oluşturma Tarihi: ' + new Date().toLocaleString('tr-TR') + '\n\n';
|
||
|
||
gcode += '; Sıcaklık Ayarları\n';
|
||
gcode += `M140 S${settings.bedTemp} ; Tabla sıcaklığı ayarla\n`;
|
||
gcode += `M104 S${settings.nozzleTemp} ; Nozzle sıcaklığı ayarla\n`;
|
||
gcode += `M190 S${settings.bedTemp} ; Tabla sıcaklığını bekle\n`;
|
||
gcode += `M109 S${settings.nozzleTemp} ; Nozzle sıcaklığını bekle\n\n`;
|
||
|
||
switch(activeTab) {
|
||
case 'x-axis':
|
||
gcode += '; X Ekseni Kalibrasyon Testi\n';
|
||
gcode += 'G28 ; Home all axes\n';
|
||
gcode += 'G90 ; Absolute positioning\n';
|
||
gcode += 'G1 Z10 F3000 ; Z eksenini kaldır\n';
|
||
gcode += `G1 X${xAxisConfig.distance} F3000 ; X ekseninde ${xAxisConfig.distance}mm hareket\n`;
|
||
gcode += 'M400 ; Hareketi tamamla\n';
|
||
gcode += `; Mevcut steps/mm: ${xAxisConfig.steps}\n`;
|
||
gcode += `; Hesaplanan yeni steps/mm: ${calculateXSteps()}\n`;
|
||
gcode += `; Firmware'e uygulamak için: M92 X${calculateXSteps()}\n`;
|
||
gcode += `; Kalıcı kaydetmek için: M500\n`;
|
||
break;
|
||
|
||
case 'y-axis':
|
||
gcode += '; Y Ekseni Kalibrasyon Testi\n';
|
||
gcode += 'G28 ; Home all axes\n';
|
||
gcode += 'G90 ; Absolute positioning\n';
|
||
gcode += 'G1 Z10 F3000 ; Z eksenini kaldır\n';
|
||
gcode += `G1 Y${yAxisConfig.distance} F3000 ; Y ekseninde ${yAxisConfig.distance}mm hareket\n`;
|
||
gcode += 'M400 ; Hareketi tamamla\n';
|
||
gcode += `; Mevcut steps/mm: ${yAxisConfig.steps}\n`;
|
||
gcode += `; Hesaplanan yeni steps/mm: ${calculateYSteps()}\n`;
|
||
gcode += `; Firmware'e uygulamak için: M92 Y${calculateYSteps()}\n`;
|
||
gcode += `; Kalıcı kaydetmek için: M500\n`;
|
||
break;
|
||
|
||
case 'z-axis':
|
||
gcode += '; Z Ekseni Kalibrasyon Testi\n';
|
||
gcode += 'G28 ; Home all axes\n';
|
||
gcode += 'G90 ; Absolute positioning\n';
|
||
gcode += `G1 Z${zAxisConfig.distance} F300 ; Z ekseninde ${zAxisConfig.distance}mm hareket\n`;
|
||
gcode += 'M400 ; Hareketi tamamla\n';
|
||
gcode += `; Mevcut steps/mm: ${zAxisConfig.steps}\n`;
|
||
gcode += `; Hesaplanan yeni steps/mm: ${calculateZSteps()}\n`;
|
||
gcode += `; Firmware'e uygulamak için: M92 Z${calculateZSteps()}\n`;
|
||
gcode += `; Kalıcı kaydetmek için: M500\n`;
|
||
break;
|
||
|
||
case 'extruder':
|
||
gcode += '; Extruder Kalibrasyon Testi\n';
|
||
gcode += 'G28 ; Home all axes\n';
|
||
gcode += 'G90 ; Absolute positioning\n';
|
||
gcode += 'M82 ; Absolute extrusion mode\n';
|
||
gcode += 'G92 E0 ; Extruder pozisyonunu sıfırla\n';
|
||
gcode += `G1 E${extruderConfig.distance} F100 ; ${extruderConfig.distance}mm filament ekstrüd et\n`;
|
||
gcode += 'M400 ; Hareketi tamamla\n';
|
||
gcode += `; Mevcut E steps/mm: ${extruderConfig.steps}\n`;
|
||
gcode += `; Hesaplanan yeni E steps/mm: ${calculateESteps()}\n`;
|
||
gcode += `; Firmware'e uygulamak için: M92 E${calculateESteps()}\n`;
|
||
gcode += `; Kalıcı kaydetmek için: M500\n`;
|
||
break;
|
||
|
||
case 'skew':
|
||
const skewValues = calculateSkew();
|
||
gcode += '; Çarpıklık Düzeltme G-Code\n';
|
||
gcode += `; XY Çarpıklık: ${skewValues.xy}°\n`;
|
||
gcode += `; XZ Çarpıklık: ${skewValues.xz}°\n`;
|
||
gcode += `; YZ Çarpıklık: ${skewValues.yz}°\n\n`;
|
||
gcode += `M852 I${skewValues.xy} J${skewValues.xz} K${skewValues.yz} ; Çarpıklık düzeltmesini uygula\n`;
|
||
gcode += 'M500 ; Ayarları kaydet\n';
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
gcode += '\n; Kalibrasyon tamamlandı\n';
|
||
gcode += 'M104 S0 ; Nozzle ısıtıcısını kapat\n';
|
||
gcode += 'M140 S0 ; Tabla ısıtıcısını kapat\n';
|
||
gcode += 'G28 X Y ; X ve Y eksenlerini home pozisyonuna getir\n';
|
||
gcode += 'M84 ; Motorları devre dışı bırak\n';
|
||
|
||
return gcode;
|
||
};
|
||
|
||
const downloadGCode = () => {
|
||
const gcode = generateGCode();
|
||
const blob = new Blob([gcode], { type: 'text/plain' });
|
||
const url = URL.createObjectURL(blob);
|
||
const a = document.createElement('a');
|
||
a.href = url;
|
||
a.download = `calibration_${activeTab}_${Date.now()}.gcode`;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a);
|
||
URL.revokeObjectURL(url);
|
||
};
|
||
|
||
const tabs = [
|
||
{ id: 'x-axis', name: 'X Ekseni', icon: Move },
|
||
{ id: 'y-axis', name: 'Y Ekseni', icon: Move },
|
||
{ id: 'z-axis', name: 'Z Ekseni', icon: Move },
|
||
{ id: 'extruder', name: 'Extruder', icon: Box },
|
||
{ id: 'skew', name: 'Çarpıklık', icon: Maximize2 },
|
||
];
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-white p-4">
|
||
<div className="max-w-6xl mx-auto">
|
||
<div className="text-center mb-8">
|
||
<h1 className="text-4xl font-bold mb-2 bg-gradient-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
|
||
3D Yazıcı Kalibrasyon
|
||
</h1>
|
||
<p className="text-slate-400">Profesyonel Kalibrasyon ve G-code Üretici</p>
|
||
</div>
|
||
|
||
<div className="bg-slate-800/50 backdrop-blur rounded-lg p-6 mb-6 border border-slate-700">
|
||
<div className="flex items-center gap-2 mb-4">
|
||
<Settings className="text-cyan-400" size={20} />
|
||
<h2 className="text-xl font-semibold">Genel Ayarlar</h2>
|
||
</div>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Tabla Sıcaklığı (°C)</label>
|
||
<input
|
||
type="number"
|
||
value={settings.bedTemp}
|
||
onChange={(e) => setSettings({...settings, bedTemp: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Nozzle Sıcaklığı (°C)</label>
|
||
<input
|
||
type="number"
|
||
value={settings.nozzleTemp}
|
||
onChange={(e) => setSettings({...settings, nozzleTemp: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Nozzle Çapı (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.1"
|
||
value={settings.nozzleDiameter}
|
||
onChange={(e) => setSettings({...settings, nozzleDiameter: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex gap-2 mb-6 overflow-x-auto">
|
||
{tabs.map((tab) => {
|
||
const Icon = tab.icon;
|
||
return (
|
||
<button
|
||
key={tab.id}
|
||
onClick={() => setActiveTab(tab.id)}
|
||
className={`flex items-center gap-2 px-4 py-3 rounded-lg transition-all whitespace-nowrap ${
|
||
activeTab === tab.id
|
||
? 'bg-gradient-to-r from-cyan-500 to-blue-500 text-white shadow-lg'
|
||
: 'bg-slate-800/50 text-slate-400 hover:bg-slate-700'
|
||
}`}
|
||
>
|
||
<Icon size={18} />
|
||
{tab.name}
|
||
</button>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
<div className="bg-slate-800/50 backdrop-blur rounded-lg p-6 border border-slate-700 mb-6">
|
||
{activeTab === 'x-axis' && (
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-4 text-cyan-400">X Ekseni Kalibrasyonu</h3>
|
||
<p className="text-slate-400 mb-6">
|
||
X ekseninin hassasiyetini ayarlamak için aşağıdaki adımları izleyin.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Hedef Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
value={xAxisConfig.distance}
|
||
onChange={(e) => setXAxisConfig({...xAxisConfig, distance: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Mevcut Steps/mm</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={xAxisConfig.steps}
|
||
onChange={(e) => setXAxisConfig({...xAxisConfig, steps: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Ölçülen Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={xAxisConfig.measured}
|
||
onChange={(e) => setXAxisConfig({...xAxisConfig, measured: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
placeholder="Test sonrası giriniz"
|
||
/>
|
||
</div>
|
||
</div>
|
||
{xAxisConfig.measured > 0 && (
|
||
<div className="bg-cyan-500/10 border border-cyan-500/30 rounded-lg p-4">
|
||
<h4 className="font-semibold text-cyan-400 mb-2">Hesaplanan Değer:</h4>
|
||
<p className="text-2xl font-bold text-cyan-300">{calculateXSteps()} steps/mm</p>
|
||
<p className="text-sm text-slate-400 mt-2">
|
||
Firmware'e uygulamak için: <code className="text-cyan-400">M92 X{calculateXSteps()}</code>
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === 'y-axis' && (
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-4 text-cyan-400">Y Ekseni Kalibrasyonu</h3>
|
||
<p className="text-slate-400 mb-6">
|
||
Y ekseninin hassasiyetini ayarlamak için aşağıdaki adımları izleyin.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Hedef Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
value={yAxisConfig.distance}
|
||
onChange={(e) => setYAxisConfig({...yAxisConfig, distance: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Mevcut Steps/mm</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={yAxisConfig.steps}
|
||
onChange={(e) => setYAxisConfig({...yAxisConfig, steps: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Ölçülen Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={yAxisConfig.measured}
|
||
onChange={(e) => setYAxisConfig({...yAxisConfig, measured: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
placeholder="Test sonrası giriniz"
|
||
/>
|
||
</div>
|
||
</div>
|
||
{yAxisConfig.measured > 0 && (
|
||
<div className="bg-cyan-500/10 border border-cyan-500/30 rounded-lg p-4">
|
||
<h4 className="font-semibold text-cyan-400 mb-2">Hesaplanan Değer:</h4>
|
||
<p className="text-2xl font-bold text-cyan-300">{calculateYSteps()} steps/mm</p>
|
||
<p className="text-sm text-slate-400 mt-2">
|
||
Firmware'e uygulamak için: <code className="text-cyan-400">M92 Y{calculateYSteps()}</code>
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === 'z-axis' && (
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-4 text-cyan-400">Z Ekseni Kalibrasyonu</h3>
|
||
<p className="text-slate-400 mb-6">
|
||
Z ekseninin hassasiyetini ayarlamak için aşağıdaki adımları izleyin.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Hedef Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
value={zAxisConfig.distance}
|
||
onChange={(e) => setZAxisConfig({...zAxisConfig, distance: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Mevcut Steps/mm</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={zAxisConfig.steps}
|
||
onChange={(e) => setZAxisConfig({...zAxisConfig, steps: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Ölçülen Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={zAxisConfig.measured}
|
||
onChange={(e) => setZAxisConfig({...zAxisConfig, measured: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
placeholder="Test sonrası giriniz"
|
||
/>
|
||
</div>
|
||
</div>
|
||
{zAxisConfig.measured > 0 && (
|
||
<div className="bg-cyan-500/10 border border-cyan-500/30 rounded-lg p-4">
|
||
<h4 className="font-semibold text-cyan-400 mb-2">Hesaplanan Değer:</h4>
|
||
<p className="text-2xl font-bold text-cyan-300">{calculateZSteps()} steps/mm</p>
|
||
<p className="text-sm text-slate-400 mt-2">
|
||
Firmware'e uygulamak için: <code className="text-cyan-400">M92 Z{calculateZSteps()}</code>
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === 'extruder' && (
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-4 text-cyan-400">Extruder Kalibrasyonu</h3>
|
||
<p className="text-slate-400 mb-6">
|
||
Extruder'ın doğru miktarda filament ekstrüd etmesini sağlayın.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Hedef Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
value={extruderConfig.distance}
|
||
onChange={(e) => setExtruderConfig({...extruderConfig, distance: parseInt(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Mevcut E Steps/mm</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={extruderConfig.steps}
|
||
onChange={(e) => setExtruderConfig({...extruderConfig, steps: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">Ölçülen Mesafe (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={extruderConfig.measured}
|
||
onChange={(e) => setExtruderConfig({...extruderConfig, measured: parseFloat(e.target.value)})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
placeholder="Test sonrası giriniz"
|
||
/>
|
||
</div>
|
||
</div>
|
||
{extruderConfig.measured > 0 && (
|
||
<div className="bg-cyan-500/10 border border-cyan-500/30 rounded-lg p-4">
|
||
<h4 className="font-semibold text-cyan-400 mb-2">Hesaplanan Değer:</h4>
|
||
<p className="text-2xl font-bold text-cyan-300">{calculateESteps()} steps/mm</p>
|
||
<p className="text-sm text-slate-400 mt-2">
|
||
Firmware'e uygulamak için: <code className="text-cyan-400">M92 E{calculateESteps()}</code>
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === 'skew' && (
|
||
<div>
|
||
<h3 className="text-2xl font-semibold mb-4 text-cyan-400">Çarpıklık Kalibrasyonu</h3>
|
||
<p className="text-slate-400 mb-6">
|
||
100x100mm kare baskı yapın ve köşegen mesafelerini ölçün.
|
||
</p>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">AC Köşegeni (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={skewConfig.ac}
|
||
onChange={(e) => setSkewConfig({...skewConfig, ac: e.target.value})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
<p className="text-xs text-slate-500 mt-1">Sol üst - Sağ alt</p>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">BD Köşegeni (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={skewConfig.bd}
|
||
onChange={(e) => setSkewConfig({...skewConfig, bd: e.target.value})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
<p className="text-xs text-slate-500 mt-1">Sağ üst - Sol alt</p>
|
||
</div>
|
||
<div>
|
||
<label className="block text-sm text-slate-400 mb-1">AD Köşegeni (mm)</label>
|
||
<input
|
||
type="number"
|
||
step="0.01"
|
||
value={skewConfig.ad}
|
||
onChange={(e) => setSkewConfig({...skewConfig, ad: e.target.value})}
|
||
className="w-full bg-slate-700 border border-slate-600 rounded px-3 py-2"
|
||
/>
|
||
<p className="text-xs text-slate-500 mt-1">Dikey köşegen</p>
|
||
</div>
|
||
</div>
|
||
<div className="bg-cyan-500/10 border border-cyan-500/30 rounded-lg p-4">
|
||
<h4 className="font-semibold text-cyan-400 mb-3">Hesaplanan Çarpıklık Değerleri:</h4>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
<div>
|
||
<p className="text-sm text-slate-400">XY Çarpıklığı</p>
|
||
<p className="text-xl font-bold text-cyan-300">{calculateSkew().xy}°</p>
|
||
</div>
|
||
<div>
|
||
<p className="text-sm text-slate-400">XZ Çarpıklığı</p>
|
||
<p className="text-xl font-bold text-cyan-300">{calculateSkew().xz}°</p>
|
||
</div>
|
||
<div>
|
||
<p className="text-sm text-slate-400">YZ Çarpıklığı</p>
|
||
<p className="text-xl font-bold text-cyan-300">{calculateSkew().yz}°</p>
|
||
</div>
|
||
</div>
|
||
<p className="text-sm text-slate-400 mt-4">
|
||
Firmware'e uygulamak için: <code className="text-cyan-400">M852 I{calculateSkew().xy} J{calculateSkew().xz} K{calculateSkew().yz}</code>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<div className="bg-slate-800/50 backdrop-blur rounded-lg p-6 border border-slate-700">
|
||
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
|
||
<div>
|
||
<h3 className="text-lg font-semibold mb-1">G-code Oluştur</h3>
|
||
<p className="text-sm text-slate-400">
|
||
Seçili kalibrasyon için G-code dosyası indir
|
||
</p>
|
||
</div>
|
||
<button
|
||
onClick={downloadGCode}
|
||
className="flex items-center gap-2 bg-gradient-to-r from-cyan-500 to-blue-500 hover:from-cyan-600 hover:to-blue-600 px-6 py-3 rounded-lg font-semibold transition-all shadow-lg hover:shadow-cyan-500/50"
|
||
>
|
||
<Download size={20} />
|
||
G-code İndir
|
||
</button>
|
||
</div>
|
||
|
||
<div className="mt-6">
|
||
<h4 className="text-sm font-semibold text-slate-400 mb-2">G-code Önizleme:</h4>
|
||
<div className="bg-slate-900 rounded-lg p-4 overflow-x-auto">
|
||
<pre className="text-xs text-green-400 font-mono whitespace-pre-wrap">
|
||
{generateGCode()}
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-6 bg-blue-500/10 border border-blue-500/30 rounded-lg p-6">
|
||
<h3 className="text-lg font-semibold text-blue-400 mb-3">📝 Kullanım Talimatları</h3>
|
||
<div className="space-y-3 text-sm text-slate-300">
|
||
<div>
|
||
<strong className="text-blue-300">X/Y/Z Ekseni Kalibrasyonu:</strong>
|
||
<ol className="list-decimal list-inside ml-4 mt-1 space-y-1">
|
||
<li>Hedef mesafeyi belirleyin (örn: 100mm)</li>
|
||
<li>Mevcut steps/mm değerinizi girin</li>
|
||
<li>G-code'u indirin ve yazıcınıza gönderin</li>
|
||
<li>Hareket tamamlandıktan sonra gerçek mesafeyi ölçün</li>
|
||
<li>Ölçülen mesafeyi ilgili alana girin</li>
|
||
<li>Hesaplanan yeni steps/mm değerini kaydedin</li>
|
||
</ol>
|
||
</div>
|
||
<div>
|
||
<strong className="text-blue-300">Extruder Kalibrasyonu:</strong>
|
||
<ol className="list-decimal list-inside ml-4 mt-1 space-y-1">
|
||
<li>Filamenti nozzle'dan 120mm işaretleyin</li>
|
||
<li>100mm ekstrüzyon komutu gönderin</li>
|
||
<li>Kalan mesafeyi ölçün ve gerçek ekstrüzyon miktarını hesaplayın</li>
|
||
<li>Ölçülen değeri girin ve yeni E steps/mm'yi uygulayın</li>
|
||
</ol>
|
||
</div>
|
||
<div>
|
||
<strong className="text-blue-300">Çarpıklık Kalibrasyonu:</strong>
|
||
<ol className="list-decimal list-inside ml-4 mt-1 space-y-1">
|
||
<li>100x100mm kalibrasyon karesi bastırın</li>
|
||
<li>Köşegen mesafeleri (AC, BD, AD) hassas ölçün</li>
|
||
<li>Değerleri girin ve çarpıklık açılarını görün</li>
|
||
<li>G-code ile düzeltmeyi uygulayın</li>
|
||
</ol>
|
||
</div>
|
||
<div className="pt-3 border-t border-blue-500/30">
|
||
<strong className="text-yellow-400">⚠️ Önemli:</strong>
|
||
<p className="mt-1">G-code komutlarını uyguladıktan sonra <code className="bg-slate-800 px-2 py-1 rounded text-yellow-300">M500</code> komutu ile ayarları kalıcı olarak kaydetmeyi unutmayın!</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
} |