Verfahrgeschwindigkeit mittels Poti einstellen

Hier gehts um die Elektronik des RF1000. Damit sind Kabel, Platinen, Endschalter und das Display gemeint.
Benutzeravatar
X4r3
Erfahrener 3D-Drucker
Erfahrener 3D-Drucker
Beiträge: 145
Registriert: Mi 25. Nov 2015, 14:04
Has thanked: 5 times
Been thanked: 48 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von X4r3 »

Danke für das Angebot, aber ich habe bei einem Platinenservice schon eine Bestellung aufgegeben.
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
▐►►► X4r3's RF1000 ◄◄◄▌
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Benutzeravatar
X4r3
Erfahrener 3D-Drucker
Erfahrener 3D-Drucker
Beiträge: 145
Registriert: Mi 25. Nov 2015, 14:04
Has thanked: 5 times
Been thanked: 48 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von X4r3 »

Ich würde sagen Verfahrensgeschindigkeit mittels Encoder einstellen läuft.
IMG_0698.jpg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
▐►►► X4r3's RF1000 ◄◄◄▌
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Benutzeravatar
RAU
Supporter
Supporter
Beiträge: 683
Registriert: Mo 28. Sep 2015, 19:16
Wohnort: NRW
Has thanked: 20 times
Been thanked: 55 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von RAU »

Ich komme nochmal auf das Thema Median Filter zurück. Auch wenn das Ausgangsproblem von X43r nun sehr gut gelöst ist, könnte sich jemand noch für die analoge Variante interessieren. Beim Lesen des Potis entstanden ja Ausreißer, die nicht so einfach herausgefiltert werden konnten...
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.
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.)

Der Grundgedanke ist ja der, dass man die letzten n Messwerte in einer Liste aufhebt, die gespeicherte Liste sortiert und dann den mittleren Wert (nicht den gemittelten Wert) zurückgibt. Das klingt nach einem Schieberegister und einem darauf angewendeten Sortierverfahren. So würde man aber jeden Wert mehrmals hin und her kopieren und hätte bestimmt keine laufzeitoptimale Lösung.

Meine Idee ist einen Ringspeicher zu verwenden, der schonmal die Schieberei erspart. Ein zweiter Ringspeicher speichert die Rangfolge der Werte. Wenn ein Wert im Speicher ersetzt wird, werden die Rangfolgewerte inkrementiell aktualisiert, das heißt man kann auf der vorherige Rangfolge aufsetzten und muss nur wenig ändern. Das klappt, indem man nur ein einziges mal durch den Ringspeicher "loopen" muss. Die Schleife ist zudem auch sehr kompakt geraten.

File median_RAU.ino:

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);
	// ...
}
Benutzeravatar
X4r3
Erfahrener 3D-Drucker
Erfahrener 3D-Drucker
Beiträge: 145
Registriert: Mi 25. Nov 2015, 14:04
Has thanked: 5 times
Been thanked: 48 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von X4r3 »

Ich hab mich heute mit dem Thema Verfahrgeschwindigkeit beim Drucken schnell ändern/einstellen nochmal beschäftigt.

Bei der Lösung mit dem Inkremental Poti musste ich feststellen dass man während bem Betriebsstatus Leerlauf die Geschwindigkeit damit sehr schnell ändern kann. Beim Drucken lässt sich die Geschwindigkeit nur Schrittweise verändern, egal wie schnell man den Poti dreht. Das liegt daran, dass die Funktion commandLoop() in die der Inkrementalpoti ausgewertet wird im Leerlauf eine Zyklusfrequenz von ca. 7,5 kHz und beim Drucken ca. 5 Hz hat.

Man könnte jetzt eine Funktion suchen die auch beim Drucken eine hohe Zyklusfrequenz hat, das ist mir aber zu riskant, nicht dass durch die Auswertung der Druck behindert wird.


Da kommt die Sache mit dem Poti und Analogwerte wieder näher. Ich habe mich letztes Jahr eine Zeit lang mit Attiny Mikrocontroller, AVR beschäftigt und eine Analogauswertung programmiert. Jetzt konnte ich Vergleiche daraus ziehen warum das in dieser Firmware für mich damals komisch programmiert war. Die Analogauswertung in der Firmware ist im AVR Stil programmiert. Hier kann (muss) man den AD-Wandler vom Mikrokontroller so konfigurieren wie man ihn braucht.

Ein weiterer Analogeingang wird folgend beschrieben:

In der RF1000.h:

#define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+BED_ANALOG_INPUTS+1) //+1

#define ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL BED_ANALOG_CHANNEL , 3} // 3 = ADC3

Der Analogwert lässt sich dann in der loopRF() Funktion in der RF.cpp mit der Variable osAnalogInputValues auslesen:

Code: Alles auswählen

	int Wert2 = osAnalogInputValues[2];
	Com::printFLN( PSTR( "Wert2: " ), Wert2 );
und Taddaaaa, keine Ausreißer mehr.

Der Index von osAnalogInputValues hängt von der jeweiligen Drucker Konfiguration ab:

Ein Extruder + Heizbett

osAnalogInputValues[0] = Temperatur Extruder 1
osAnalogInputValues[1] = Temperatur Heizbett
osAnalogInputValues[2] = Poti


Umsetzung der Änderung der Verfahrgeschwindigkeit im Code folgt.



Firmwarestand: V RF.01.11
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
▐►►► X4r3's RF1000 ◄◄◄▌
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Benutzeravatar
Nibbels
Developer
Developer
Beiträge: 2264
Registriert: Mi 17. Aug 2016, 17:01
Has thanked: 831 times
Been thanked: 598 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von Nibbels »

Hi :)

Ich kann dir nicht sagen, wie das bei 1.11 aussieht, aber bei 1.37 und vermutlich auch kleinerer Version kannst du:
https://github.com/Nibbels/Repetier-Fir ... .cpp#L4869
Funktion fastAction()
extrem wiederholfreudige Aufgaben einbinden.
Vermutlich ist es natürlich gut, wenn diese nicht lange dauern.
Diese Funktion hängt mit einem Frequenzteiler in ISR(PWM_TIMER_VECTOR)
Ich bin mir nicht sicher, aber ich vermute einen 1khz / 1ms Takt.
Dort drüber läuft z.B. die Erkennung des Loslassens der Z-Down und Z-Up-Taste.
Wenn du Variablen von nem Interrupt veränderbar machst, deklariere die Variable evlt. auch als "volatile".
Sonst könnte dir die Compileroptimierung einen Fehler einbauen.

Beim RF2000 sind im übrigen die Pins
PJ0, PJ1, PE4
frei. Bzw. liegen auf
Screenshot_1.png

Noch was:

Beim RF2000 gibts:
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 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?

Übrigends ziemlich cooles Projekt, ich habs leider erst heute entdeckt :)

LG
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
RF2000
Firmware Mod 1.45.00.Mod - geht SD wieder 100%?

Bitte 1.42.17 bis 1.42.21 meiden!
SD-Druck mit der Community-FW <= 1.43.99 aktuell meiden.
Benutzeravatar
X4r3
Erfahrener 3D-Drucker
Erfahrener 3D-Drucker
Beiträge: 145
Registriert: Mi 25. Nov 2015, 14:04
Has thanked: 5 times
Been thanked: 48 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von X4r3 »

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?
Ich denke die Angabe bei #define ANALOG_INPUT_CHANNELS kommt von der ADC Nummer.

Die 3 definiert den ADC3 = Register PF3 = Hardwarepin 94

In der RF1000.h:
EXT0_ANALOG_CHANNEL = 13 = ADC13 = Register PK5 = Hardwarepin 84
EXT1_ANALOG_CHANNEL = 14 = ADC14 = Register PK6 = Hardwarepin 83
BED_ANALOG_CHANNEL = 15 = ADC15 = Register PK7 = Hardwarepin 82

Ich müsste mal im ATMEGA2560 Datenblatt nachschauen welche freien Pins der Option IO Schnittstelle vom RF1000 man als Analogeingang nutzen kann, aber auf jeden fall kann man PF3 (ADC3) und PF4 (ADC4) als Analogeinang nutzen.




Folgenden Code habe ich in der loopRF() Funktion in der RF.cpp implementiert:

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);
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. :traurig:
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
▐►►► X4r3's RF1000 ◄◄◄▌
▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
Benutzeravatar
Nibbels
Developer
Developer
Beiträge: 2264
Registriert: Mi 17. Aug 2016, 17:01
Has thanked: 831 times
Been thanked: 598 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von Nibbels »

Bei uns im Mod haben wir die Feedrate über die Tasten "Retract" und "Feed" verstellbar gemacht. Die Tasten haben im Menü 2, dem Modmenü eben andere Funktionen bekommen.
Und die Sache mit der Verzögerung tritt bei uns auch auf. Mich hat das aber bisher nicht weiter gestört.

Evtl. helfen dir auch diese Hinweise weiter:
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
Das mit den Pinzuweisungen recherchiere ich gerade.
Wenn 13 der ADC13 sein soll, gibts da ne Liste, was nach ADC16 käme? Die 17 für Digital IO 1??
Das ist nur spekuliert, ...
Da knabbere ich noch dran:
"Wieso ist in Pins.h eine völlig andere Zahlennotation wie bei den Hardwarepins?"
"Wird das irgendwo in der Firmware übersetzt??"

Edit: Da gibts n Bild: https://www.arduino.cc/en/Hacking/PinMapping2560
Ahh :D
Die Pinnummern sind in Analog und Digital geteilt.
Analog 0..15
Digital 0..53?
Und jeweils die Funktion die sie "benutzt" entscheidet anscheinend, welcher Hardwarepin wirklich betroffen ist.

:geheim: Genau das wurde auf den seiten vorher diskutiert... Umpf.

LG
RF2000
Firmware Mod 1.45.00.Mod - geht SD wieder 100%?

Bitte 1.42.17 bis 1.42.21 meiden!
SD-Druck mit der Community-FW <= 1.43.99 aktuell meiden.
Benutzeravatar
Nibbels
Developer
Developer
Beiträge: 2264
Registriert: Mi 17. Aug 2016, 17:01
Has thanked: 831 times
Been thanked: 598 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von Nibbels »

RF2000
Firmware Mod 1.45.00.Mod - geht SD wieder 100%?

Bitte 1.42.17 bis 1.42.21 meiden!
SD-Druck mit der Community-FW <= 1.43.99 aktuell meiden.
Benutzeravatar
Nibbels
Developer
Developer
Beiträge: 2264
Registriert: Mi 17. Aug 2016, 17:01
Has thanked: 831 times
Been thanked: 598 times

Re: Verfahrgeschwindigkeit mittels Poti einstellen

Beitrag von Nibbels »

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. :traurig:
Ich will mich hier nochmal kurz melden, weil ich den Thread wieder sah.
Im Mod gibts inzwischen eine "Technik" mit der man die Geschwindigkeit in Echtzeit ändern kann. Man könnte also den Poti dort einhaken.

LG
RF2000
Firmware Mod 1.45.00.Mod - geht SD wieder 100%?

Bitte 1.42.17 bis 1.42.21 meiden!
SD-Druck mit der Community-FW <= 1.43.99 aktuell meiden.
Antworten

Zurück zu „Elektronik“