Ich habe aus eigenem Interesse etwas im Sourcecode der 1.33 gelesen.
g_abortZScan =
0 -> Kein Fehler.
g_abortZScan =
1 -> Abbruchbedingung erreicht.
Was dann
#define UI_TEXT_HEAT_BED_SCAN_ABORTED "Scan aborted"
auslöst.
Das passiert im
Druckerbetrieb, wenn:
a) mehr Punkte in X ausgelesen werden, als die Matrix größe hat:
Code: Alles auswählen
if( nIndexX > COMPENSATION_MATRIX_MAX_X )
{
if( Printer::debugErrors() )
{
Com::printFLN( PSTR( "scanHeatBed(): the x-dimension of the compensation matrix became too big: " ), nIndexX );
}
g_abortZScan = 1;
break;
}
b) Wenn mehr Punkte in Y ausgelesen werden, als die Matrix größe hat:
Code: Alles auswählen
if( nIndexY > COMPENSATION_MATRIX_MAX_Y )
{
if( Printer::debugErrors() )
{
Com::printFLN( PSTR( "scanWorkPart(): the y-dimension of the compensation matrix became too big: " ), nIndexY );
}
g_abortZScan = 1;
break;
}
c) die Ruhekraft nicht korrekt ermittelt werden kann:
Code: Alles auswählen
// scan this point
if( testIdlePressure() )
{
// the current idle pressure is not plausible
g_abortZScan = 1;
break;
}
a) und b) dürften per Definition nie auftreten, ausser jemand schreibt die anzahl der Punkte um.
c) bleibt übrig.
-----------------------------------------
Also gibt es mit ziemlicher Sicherheit ein Problem mit der Funktion die den Ruhe-Kraft-Mittelwert bildet.
testIdlePressure()
Code: Alles auswählen
short testIdlePressure( void )
{
short nTempPressure;
short nTemp;
if( readAveragePressure( &nTempPressure ) )
{
// some error has occurred
if( Printer::debugErrors() )
{
Com::printFLN( PSTR( "testIdlePressure(): the pressure could not be determined" ) );
}
return -1;
}
g_nCurrentIdlePressure = nTempPressure;
return 0;
} // testIdlePressure
Bzw. darunterliegend:
readAveragePressure
Code: Alles auswählen
g_nScanPressureReads = HEAT_BED_SCAN_PRESSURE_READS; //=15
g_nScanPressureReadDelay = HEAT_BED_SCAN_PRESSURE_READ_DELAY_MS; //=15
g_nScanPressureTolerance = HEAT_BED_SCAN_PRESSURE_TOLERANCE; //=15
ACTIVE_STRAIN_GAUGE //=> 0x49
Code: Alles auswählen
short readAveragePressure( short* pnAveragePressure )
{
short i;
short nTempPressure;
short nMinPressure;
short nMaxPressure;
long nPressureSum;
char nTemp;
nTemp = 0;
while( 1 )
{
// we read the strain gauge multiple times and check the variance
nPressureSum = 0;
nMinPressure = 32000;
nMaxPressure = -32000;
for( i=0; i<g_nScanPressureReads; i++)
{
#if FEATURE_WATCHDOG
HAL::pingWatchdog();
#endif // FEATURE_WATCHDOG
HAL::delayMilliseconds( g_nScanPressureReadDelay );
nTempPressure = readStrainGauge( ACTIVE_STRAIN_GAUGE );
nPressureSum += nTempPressure;
if( nTempPressure < nMinPressure ) nMinPressure = nTempPressure;
if( nTempPressure > nMaxPressure ) nMaxPressure = nTempPressure;
}
nTempPressure = (short)(nPressureSum / g_nScanPressureReads);
if( (nMaxPressure - nMinPressure) < g_nScanPressureTolerance )
{
// we have good results
*pnAveragePressure = nTempPressure;
return 0;
}
nTemp ++;
if( nTemp >= 5 )
{
// we are unable to receive stable values - do not hang here forever
if( Printer::debugErrors() )
{
Com::printF( PSTR( "readAveragePressure(): the pressure is not constant: " ), nMinPressure );
Com::printF( PSTR( " / " ), nTempPressure );
Com::printFLN( PSTR( " / " ), nMaxPressure );
}
break;
}
// wait some extra amount of time in case our results were not constant enough
HAL::delayMilliseconds( 100 );
//runStandardTasks();
Commands::checkForPeriodicalActions();
}
if( Printer::debugErrors() )
{
Com::printFLN( PSTR( "readAveragePressure(): the pressure is not plausible" ) );
}
g_abortZScan = 1;
*pnAveragePressure = 0;
return -1;
} // readAveragePressure
Die darunterliegende Funktion readStrainGauge( ACTIVE_STRAIN_GAUGE ); erfasst einfach nur den Messwert und ist hier vermutlich uninteressant.
Diese Funktion `
readAveragePressure` summiert also (
g_nScanPressureReads mal)
15 mal den Kraftwert und schreibt mit, welches der kleinst und welches der größte gemessene Kraftwert war, welcher auftrat.
Die Summe der Kraftwerte ergibt den Mittelwert.
Aber dem Mittelwert wird nicht blind vertraut:
Nun wird geschaut, ob die Streuung der Ruhe-Digits, der Abstand zwischen MIN und MAX, nicht größer ist, als (
g_nScanPressureTolerance)
15.
Stimmt das nicht, wird fünf weitere Male ausprobiert, ob es klappt und dann abgebrochen.
->
Scan Aborted.
Die Frage ist also:
Warum ist der Messwert in diesen knapp 250ms
(15ms x 15 Messungen) nicht konstant?
(Und: Warum ist dieser ganze 5x hintereinander nicht konstant/ungültig?)
a) Vibriert irgendwas so, dass der Kraftsensor das `hört`?
b) Ist das Messsignal schlecht?
c) Stört etwas das Messsignal durch Übersprechen?
d) Existiert ein mechanisches Nachschwingen?
e) Hängt ein Lüfter mit Unwucht am Extruder?
f) ???
Wenn das Nachschwingen das Problem wäre, und nicht ein Lüfter oder ähnliches, dann:
Vor diesen Mittelungen wird immer um
g_nScanIdleDelay gewartet.
Diese Variable wird mit
Code: Alles auswählen
g_nScanIdleDelay = HEAT_BED_SCAN_IDLE_DELAY_MS; //=250
initialisiert.
Und es gibt dazu
M3042
Code: Alles auswählen
case 3042: // M3042 [S] - configure the delay (in ms) between reaching of a new x/y position and the test of the idle pressure
{
if( pCommand->hasS() )
{
// test and take over the specified value
nTemp = pCommand->S;
if( nTemp < 1 ) nTemp = 1;
if( nTemp > 10000 ) nTemp = 10000;
g_nScanIdleDelay = nTemp;
if( Printer::debugInfo() )
{
Com::printF( PSTR( "M3042: new idle delay: " ), (int)g_nScanIdleDelay );
Com::printFLN( PSTR( " [ms]" ) );
}
}
else
{
showInvalidSyntax( pCommand->M );
}
break;
}
Für mich sieht das so aus, als könnte ich den Wert zur Laufzeit mit diesem G-Code überschreiben und höhere Werte testen.
Oder man ändert:
auf >5.
Doch... wenn ein Test 15x15ms Zeit braucht und es 5x nicht klappt, hätte der Extruder insgesamt über 1 Sekunde nachgeschwungen + Delay zu Beginn. Also etwa 1,25s ausschwingen und noch keine Ruhe im System? Naja ...
LG