Jump to content

Funktionsweise Encoder


batuu
 Share

Recommended Posts

Hallo,

ich hab mal eine verständnisfrage zu der ganzen encoder geschichte.

nur zur funktionsweise ...

die encoder werden an die schiftregister angeschlossen. wie wird erkannt, ob an einem encoder gedreht wurde? werden zyklisch die register durchgeschiftet und dann alter mit neuem zustand verglichen?

es ist schwierig sich in dieses MIOS reinzulesen ... kann mir jemand das grundsätzliche prinzip erklären, wie die encoder ausgewertet werden?

mfg batuu

Link to comment
Share on other sites

encoder sind praktisch wie 2 Taster, welche in reihe geschaltet sind.

du legst in der mitte eine spannung an und je nachdem welchen taster du drückst

liegt halt bei einem Ausgang dei spannung an.

die encoder sind meistens gerastert (detendend, meistens 24 schritte/umdrehung)und geben pro rasterung ein signal aus.

Bei welchem Ausgang (1 oder 2) das signal rauskommt hängt von der drehrichtung ab.

ich hoffe ich konnte dir damit helfen

Link to comment
Share on other sites

die encoder werden an die schiftregister angeschlossen. wie wird erkannt, ob an einem encoder gedreht wurde? werden zyklisch die register durchgeschiftet und dann alter mit neuem zustand verglichen?

Ja, genau so funktioniert das.

In der MIOS-ISR (Interrupt Service Routine; zu finden in mios_isr.inc) wird jede Millisekunde durch einen Timer die Funktion MIOS_ENC_Tick aufgerufen, die prüft, ob ein Encoder bewegt wurde.

In der MIOS Mainloop (mios_mainloop.inc) wird ebenfalls zyklisch (aber nicht Timer-gesteuert!) die Funktion MIOS_ENC_Handler aufgerufen, die dann die Funktion USER_ENC_NotifyChange in der jeweiligen Applikation (z.B. MB64E) aufruft, wenn ein Encoder bewegt wurde.

Ich hoffe, dass hilft Dir weiter. Wie sagt Thorsten immer: MIOS is a text adventure ;)

Raphael

Link to comment
Share on other sites

  • 6 years later...

Ich hole diesen alten Thread nochmals hoch da ich zu dem Thema auch noch eine Frage habe:

 

Ich benötige Encoder die je nach Drehrichtung pro Rastpunkt eine andere Midi Note On senden. 

Kann ich die Encoder dann ohne das ich den Code anpassen muss anstelle eines Tasters ans DIN anschließen oder muss ich im Code extra die Pins als Encoder definieren?

Edited by Obi_hh
Link to comment
Share on other sites

Hallo,

 

Wenn ich das richtig verstehe, meinst Du so was wie beispielsweise Rechtsdrehung = Note C und Linksdrehung = Note D, ist das richtig?

Das wird ohne zusätzliche Programmierung nicht funktionieren, denke ich. Zwei Punkte sind da zu beachten bei Encodern:

 

1. Ein gerasteter Encoder gibt beim Erreichen eines Rastpunkts mehr als nur einen Impuls aus (encoderabhängig). D.h. wenn eine Tastfunktion damit gesteuert werden soll, kann es passieren, dass Du beim "Sprung" von einem zum nächsten Rastpunkt diese "Taste" mehrfach betätigst. Das muss nicht bei allen gerasteten Encodern so sein, aber bei den üblicherweise hier verwendeten ist das so. Es gibt die Möglichkeit, das beim Definieren der Hardwarekomponenten in der Firmware auszugleichen ("encoder type"), aber so hundertprozentig verlässlich ist das nicht.

2. Es ist richtig, dass ein Encoder an zwei DIN Eingänge angeschlossen wird (äquivalent zu 2 Tastern), aber bei Betätigung des Encoders in eine Richtung wird nicht nur ein DIN Anschluss angeprochen, sondern beide abwechselnd. Beispielsweise bei Drehung (mit DIN A und B) in eine Richtung wird nicht A-A-A-A-A-.... ausgegeben, sondern A-B-A-B-A-B-....

Dies hat zu tun mit der Möglichkeit, die Geschwindigkeit bei der Drehung zu erfassen und umzusetzen (glaube ich :rolleyes: ). Auch hier muss das nicht auf alle Encoder zutreffen, aber auf die üblichen schon.

 

Es ist also nicht so einfach, zwei Taster durch einen Encoder zu ersetzen, leider...

 

Hier kommst Du zu einer Wikiseite, die ein paar Infos zu verschiedenen Encodern hat.

 

 

Was möchtest Du denn steuern? Vielleicht gibt es noch andere Möglichkeiten, deine Ideen umzusetzen.

 

Liebe Grüße

 

 

 

EDIT: Mir fiel gerade ein, dass deine Idee vielleicht software-seitig gelöst werden könnte mithilfe von if-Befehlen und relativen Encoder-Events. Habs noch nicht selbst versucht, aber denkbar wäre das schon. Ich kann nicht sagen, ob man das so hinbiegen kann, dass das auch mit den Rastpunkten des Encoders 100%ig übereinander passt, das müsste man halt mal ausprobieren.

Edited by John E. Finster
Link to comment
Share on other sites

Dankeschön,  hab ich schon so ähnlich vermutet!  Ja Richtig, er sollte bei Rechtsdrehung z.b. Note A, bei Links Note B senden.  Das liegt daran das ich den Wert in der Software mittels inc und dec veränderen möchte. Gibts die Möglichkeit in Mios / C das zu lösen?

Link to comment
Share on other sites

Zunächst denke ich mal, Du solltest Dir mal das neue Midibox_NG Konzept anschauen. Auf den Controller wird hierbei die MB_NG Firmware als eine Art "Framework" draufgeladen. Welche Hardwareelemente benutzt werden sollen und welche Aufgaben diese erledigen sollen, wird über ein Skript gesteuert, das auf einer SD Karte liegt und das über das Mios Studio direkt bearbeitet werden kann. Es ist also nicht notwendig, Mios direkt zu modifizieren. Auch Programmiersprachen wie C oder ähnliche werden dafür nicht benötigt. 

Das mal als Info.

 

Im Skript selbst kann dem Encoder ein relativer Modus zugeordnet werden, d.h. bei Drehung rechts wird immer der Wert 63 gesendet, bei Drehung links immer 64 (oder so...).

Dann gibt es bestimmte Befehle im Skript, wie beispielsweise Event_Sender oder Event_Receiver und If-Befehle, mit denen ein Midievent in ein anderes "übersetzt" werden kann.

Daher kann ich mir vorstellen, dass es möglich ist, die Events, die ein relativer Encoder sendet, also entweder 63 oder 64 (bei CC-Events) in verschiedene Noten zu übersetzen, die dann ausgegeben werden.

Wie gesagt, ich habe es noch nicht selbst probiert, mein Gerät ist noch nicht ganz fertig, aber ich denke mal, so könnte das funktionieren.

Link to comment
Share on other sites

Danke für die Info,  ich habe allerdings den alten ncore mit dem pic 18F452 und wolte dieses nicht ändern da das system so läuft wie es soll...  nun war allerdings die Ãœberlegung ob ich 4 der 64 Taster weglasse und dafür dann 2 Encoder montiere.  Das einzige Problem ist das ich mein Programm vom encoder aus nicht mit CC werten sondern mit 2 Noten für "inc" und dec" ansteuern will.  Ist das mit dem Relativen Modus auch in C Möglich?

Link to comment
Share on other sites

  • 3 weeks later...

Hallo MIDIbox Newbie

 

In meinem DIY-Synth verwende ich fünf Drehgeber (ALPS STEC12E) für die Menüsteuerung und Dateneingabe. Die Abfrage der Drehgeber (Encoder) erfolgt in meinem Source-Code über einen Timer-Interrupt jede 1msec. Die Encoder-Daten von -128 bis  +127 werden in Variablen "enc1_delta" zwischengespeichert und im Hauptprogramm ausgewertet. Zusätzlich ist noch eine dynamische Drehbeschleunigung integriert. Vielleicht hilft dir der Code für dein Projekt.

 

Hier der C-Code (ATXmega) für einen einen Drehgeber:

//-------------------------------------------------------------------------
// PORT-PIN Defination Encoder
//
#define enc1_PHASEA     (PORTE.IN & 1<<PIN0)	// an Pinbelegung anpassen
#define enc1_PHASEB     (PORTE.IN & 1<<PIN1)	// an Pinbelegung anpassen

// init Port Encoder_1
PORTE.DIR &= ~(1<<PIN0);		// init Port-Direction to IN
PORTE.DIR &= ~(1<<PIN1);
PORTE.PIN0CTRL = 0x38;			// set Port Pullup
PORTE.PIN1CTRL = 0x38;

volatile int8_t enc1_delta = 0;			// -128 ... 127
uint8_t enc1_dynamic = 3;

const int8_t table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0};

//*************************************************************************
// Timer 3 interrupt (priority low) 1msec
// encoder-polling
//*************************************************************************

// values for enc-dynamic
#define ENCODER_ACCEL_TOP    1536
#define ENCODER_ACCEL_INC	 96
#define ENCODER_ACCEL_DEC    1

ISR(TCE1_OVF_vect )
{
	int8_t new_x, diff_x;
		
	// read encoder 1 -----------------------------------------------------	
	static int8_t last_1;
	static int8_t last_1temp;
	static int16_t Enc1Accel;
	
	// slowing (Entschleunigung)
	Enc1Accel -= ENCODER_ACCEL_DEC;		// wird hier zuviel subtrahiert,
	if (Enc1Accel & 0b1000000000000000)	// wird EncAccel negativ, und
	Enc1Accel = 0;
	
	// read enc pin and convert gray to binary
	new_x = 0;
	last_1 = (last_1 << 2)  & 0x0F;
	if (enc1_PHASEA) last_1 |=2;
	if (enc1_PHASEB) last_1 |=3;
	new_x += pgm_read_byte(&table[last_1]);
	
	// difference last - new
	diff_x = last_1temp - new_x;					// difference last - new
	last_1temp = new_x;								// save new to last
	
	if (diff_x > 0)
	{
		// direction
		if (last_1 > 0)
		enc1_delta -= 1+(Enc1Accel >> 6);  // diff_1: xxxxxx11
		else
		enc1_delta += 1+(Enc1Accel >> 6);  // diff_1: xxxxxx01
		
		// acceleration (Beschleunigung)
		if (Enc1Accel <= (ENCODER_ACCEL_TOP - enc1_dynamic))	
		Enc1Accel += enc1_dynamic;
	}

//-------------------------------------------------------------------------
// get encoder value
//
int8_t encode1_read(void)         // read four step encoders
{
	int8_t val;
	cli();						 // atomarer Variablenzugriff
	val = enc1_delta;
	enc1_delta = 0;
	sei();
	return val;
}

 

Grüße Rolf

Edited by rolfdegen
Link to comment
Share on other sites

In MIOS8/MIOS32 muss man den Encoder-Handler nicht von Hand programmieren, das ist schon alles eingebaut.

 

Hier das Programmierbeispiel fuer MIOS8: http://www.ucapps.de/mios_c_send_enc_rel.html

Und hier fuer MIOS32 (just for completeness): http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Ftutorials%2F014_enc_relative%2Fapp.c

 

 

 

Ja Richtig, er sollte bei Rechtsdrehung z.b. Note A, bei Links Note B senden.  Das liegt daran das ich den Wert in der Software mittels inc und dec veränderen möchte. Gibts die Möglichkeit in Mios / C das zu lösen?

 

Im MIOS8 Tutorial die ENC_NotifyChange Funktion ersetzen durch:


void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam
{
  MIOS_MIDI_TxBufferPut(0x90);           // Note On at MIDI Channel #1
  MIOS_MIDI_TxBufferPut(incrementer > 0 ? 0x3d : 0x3c); // different note depending on direction
  MIOS_MIDI_TxBufferPut(0x7f); // full velocity
}

 

 

 

Gruss, Thorsten.

Link to comment
Share on other sites

  • 7 months later...

Klar, wenn Du die MIDIbox NG Applikation verwendest, definierst Du die Pin-Belegung ja nicht in der Firmware, sondern in Deinem .NGC File.

 

Hier muessen lediglich die beiden Pin-Zuweisungen vertauscht werden.

 

Beispiel: aus

ENC n=  1   sr= 1  pins=0:1   type=non_detented

wird:

 

ENC n=  1   sr= 1  pins=1:0   type=non_detented

Gruss, Thorsten.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...