Re: Verfahrgeschwindigkeit mittels Poti einstellen
Verfasst: Do 25. Feb 2016, 13:51
Danke für das Angebot, aber ich habe bei einem Platinenservice schon eine Bestellung aufgegeben.
Da ich gerade in die Arduino Programmierung schnuppere, habe ich mal so einen Median Filter geschrieben. Ich glaube es ist eine gute (schnelle) Lösung entstanden. (Es wurde aber doch mehr eine C-Übung als eine Arduino Übung.)RAU hat geschrieben:Eine Mittelwertbildung hat den Nachteil, dass sie um so träger wird, je besser sie filtert. Wenn es nur darum geht, Ausreißer wegzukriegen, wäre es besser einen nichtlinearen aber sehr pragmatischen Ansatz zu wählen, z.B. den Median Filter. Du sammelst die letzten 3, 5 oder 7 Messwerte und berücksichtigst nur der Größe nach sortiert (!) den Mittleren. Der Ausreißer wird niemals in der Mitte der sortierten Liste landen.
Um auch leichtes Rauschen noch herauszufiltern, müsste man den Mittelwertfilter noch oben draufsetzen.
Code: Alles auswählen
// ------------------------
// median filter by RAU
// Ratingen 25.03.2016
// for the public domain
// ------------------------
// Median filter for a serial data stream.
// Stores a static array with the last 3/5/7/... values of the data stream.
// Each call remplaces the oldest value of the array by the new one.
// The median value, which is in the middle of the ordered array, is returned.
// Fast processing: Only one loop. Ring structure instead of shift register.
// Order of unchanged values is reused and incrementally updated.
// Initialization at the first call: The array is filled with the first value.
// Sorry, only one channel. Copy complete function with renamed constants for more.
// (This allows to use different data types and compiles into faster code.)
#define storageSize 7 // size of filter, only odd numbers 3/5/7/... allowed
#define medianPos 3 // position of median in ordered list: (storageSize-1)/2,
// don't let the processor calculate this in the loop
#define medianType int // type of data values (int/long/float/...)
medianType median(medianType newVal) {
static int init = 1; // init flag
static medianType storageVal[storageSize]; // array of values
static medianType storageOrd[storageSize]; // array of order numbers
static int actual = 0; // actual index of the ring storage
medianType returnVal = newVal; // the new value could be the median
if (init) {
// initialization of arrays
int i;
for (i=0; i<storageSize; i++) {
storageVal[i] = newVal; // fill array with new value
storageOrd[i] = i; // just spread all order values
}
init = 0; // don't run initialization again
} else {
// store new value
if (++actual >= storageSize) actual=0; // go one step in ring storage
medianType oldVal = storageVal[actual]; // save old value
int oldOrd = storageOrd[actual]; // save old order number
storageVal[actual] = newVal; // store new value
storageOrd[actual] = 0; // reset order number for new value
// main loop
int c = actual; // index for loop through ring storage
if (++c >= storageSize) c=0; // go one step (don't process actual position)
do {
if (newVal <= storageVal[c] && oldOrd > storageOrd[c])
storageOrd[c]++; // bigger value removed, smaller value added
else if (newVal > storageVal[c] && oldOrd < storageOrd[c])
storageOrd[c]--; // smaller value removed, bigger value added
if (storageOrd[c] == medianPos)
returnVal = storageVal[c]; // median found
if (newVal > storageVal[c])
storageOrd[actual]++; // calculate order of new value
if (++c >= storageSize) c=0; // go one step in ring storage
} while (c != actual); // stop at actual position
}
// return new median value
return (returnVal);
}
// dummy arduino sketch, only to show how easy the filter is used:
#define analogPin A0
int analogVal;
int medianVal;
void setup()
{
}
void loop()
{
// ...
analogVal = analogRead(analogPin);
medianVal = median(analogVal);
// ...
}
Code: Alles auswählen
int Wert2 = osAnalogInputValues[2];
Com::printFLN( PSTR( "Wert2: " ), Wert2 );
Ich habe für den RF2000 den dritten Temperatursensor aktiviert. Und nun ne Frage:rf2000.h hat geschrieben:Code: Alles auswählen
/** \brief number of analog input signals. Normally 1 for each temperature sensor */ #define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+BED_ANALOG_INPUTS+RESERVE_ANALOG_INPUTS)
Code: Alles auswählen
#define ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL BED_ANALOG_CHANNEL RESERVE_ANALOG_CHANNEL}
Ich denke die Angabe bei #define ANALOG_INPUT_CHANNELS kommt von der ADC Nummer.Nibbels hat geschrieben: Ich habe für den RF2000 den dritten Temperatursensor aktiviert. Und nun ne Frage:
Unter ANALOG_INPUT_CHANNELS liste ich Pin-Nummern auf, wie ich verstanden habe.
Du machst dahinter einfach ", 3" und kommentierst das als Analog-Channel 3. Komma ist klar, das ist im #define versteckt.
Zurückrecherchiert heißt (RF1000 und RF2000)BED_ANALOG_CHANNEL -> KOMMA HEATED_BED_SENSOR_PIN -> TEMP_2_PIN -> Pin 15 siehe pins.h.
Aber dein Pin 3 ist doch was anderes, nämlich ORIG_X_MIN_PIN oder beim RF2000 der OUTPUT_230V_PIN??
Völlig klar, dass ich mich irren kann, doch gibts dafür ne Erklärung?
Code: Alles auswählen
int Wert2 = osAnalogInputValues[2];
Com::printFLN( PSTR( "Wert2: " ), Wert2 );
float feedrate = 100;
if ( Wert2 < 2047 )
{
feedrate = 10.0 + (((float)Wert2) * (90.0/2048.0));
Com::printFLN( PSTR( "feedrate kleiner: " ), feedrate );
}
if ( Wert2 > 2048 )
{
feedrate = 100.0 + (((float)Wert2-2048) * (300.0/2048.0));
Com::printFLN( PSTR( "feedrate grosser: " ), feedrate );
}
Com::printFLN( PSTR( "feedrate: " ), (int)feedrate );
Com::printFLN( PSTR( "Printer::feedrateMultiply: " ), Printer::feedrateMultiply );
Com::printFLN( PSTR( "Printer::feedrate: " ), Printer::feedrate );
Commands::changeFeedrateMultiply((int)feedrate);
Das mit den Pinzuweisungen recherchiere ich gerade.rf1000.h / rf2000.h hat geschrieben:Code: Alles auswählen
/** \brief Number of moves we can cache in advance. This number of moves can be cached in advance. If you wan't to cache more, increase this. Especially on many very short moves the cache may go empty. The minimum value is 5. */ #define MOVE_CACHE_SIZE 16 /** \brief Low filled cache size. If the cache contains less then MOVE_CACHE_LOW segments, the time per segment is limited to LOW_TICKS_PER_MOVE clock cycles. If a move would be shorter, the feedrate will be reduced. This should prevent buffer underflows. Set this to 0 if you don't care about empty buffers during print. */ #define MOVE_CACHE_LOW 10
Ich will mich hier nochmal kurz melden, weil ich den Thread wieder sah.X4r3 hat geschrieben: Der Speed Mul. lässt sich mit dem Poti von 10% (25%) - 400% sehr schnell einstellen. Allerdings ändert sich die Verfahrgeschwindigkeit beim Drucken nicht sofort sondern erst nach ein paar Bahnen auf den eingestellten Wert. Das liegt warscheinlich daran, dass immer ein paar G-Code Befehle vorraus gepuffert werden.
Das habe ich mir nicht so Vorgestellt.