Forum: Mikrocontroller und Digitale Elektronik Drehgeber code


von Programist (Gast)


Lesenswert?

Hi, Ich habe einige Fragen zu diesem Code hier:
1
-- I use PortD:2 and PortD:3 as inputs for the rotary switch. 
2
-- The codeworks fine.
3
4
5
var byte OldEncoderValue
6
OldEncoderValue = ((PORTD >> 2) & 0b00000011)
7
8
function ReadEncoder (byte in Value) return byte is
9
var byte EncoderValue
10
var byte EncoderTemp
11
EncoderValue = ((PORTD >> 2) & 0b00000011)
12
if(EncoderValue != OldEncodervalue)then
13
C = Low
14
OldEncoderValue = (OldEncoderValue & 0b00000001) << 1
15
EncoderTemp = OldEncoderValue ^ EncoderValue
16
if((EncoderTemp == 0) | ((EncoderTemp - 1) == 0)) then
17
Value = Value - 1
18
else
19
Value = Value + 1
20
end if
21
end if
22
OldEncoderValue = EncoderValue
23
return Value
24
end function

Ich habe ihn ausprobiert und es läuft, aber Ich möchte die Pinbelegung 
ändern.Wie kann man das tun?
Ausserdem verstehe Ich nicht was das hier soll: "C = Low"
Ich vermute das ist das "Carry bit", aber ist es nötig ihn zu löschen?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Programist schrieb:
> Ich möchte die Pinbelegung ändern.Wie kann man das tun?
Welche Ports willst du denn nehmen?
Am einfachsten wäre es, irgendwelche zwei anderen nebeneinanderliegenden 
Bits zu nehmen. die mußt du dann nur noch (anders) zurechtrücken...
Hier werden z.B. der Port D.2 und D.3 verwendet:
EncoderValue = ((PORTD >> 2) & 0b00000011)

Und wenn du Port B.4 und B.5 verwenden willst, dann mußt du das machen:
EncoderValue = ((PORTB >> 4) & 0b00000011)

Kompizierter wirds, wenn du Port A.6 und C.3 nehmen willst:
EncoderValue = (((PORTA>>5)&0b00000010) | ((PORTC>>4)&0b00000001))

Das Ganze nennt sich Bitmanipulation...

> Ausserdem verstehe Ich nicht was das hier soll: "C = Low"
> Ich vermute das ist das "Carry bit", aber ist es nötig ihn zu löschen?
Wo wird das Ding denn überhaupt verwendet?

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> OldEncoderValue = ((PORTD >> 2) & 0b00000011)

machstu draus:

OldEncoderValue = ((DeinPort >> PinAufDemPort) & 0b0000001) | 
(DeinAndererPort >> (PinAufDemAnderenPort - 1)) & 0b00000010)

dito für EncoderValue

Was ist das eigentlich für eine Sprache? Sieht aus, wie ein Bastard aus 
Pascal, C und Basic!

von Programist (Gast)


Lesenswert?

Philipp Klostermann schrieb:
> Was ist das eigentlich für eine Sprache? Sieht aus, wie ein Bastard aus
>
> Pascal, C und Basic!

Genau, Das ist Jal.
http://www.casadeyork.com/jalv2/

Lothar Miller schrieb:

> Wo wird das Ding denn überhaupt verwendet?

Genau weiss Ich nicht.Ich habe nur dieses Fragment hier gefunden
http://tech.dir.groups.yahoo.com/group/jallist/message/26296 und das 
war's.

Aber danke für eure Antworten, Ich werde ausprobieren ob es geht die 
pins auf diese Weise zu ändern.

von Achim M. (minifloat)


Lesenswert?

KannstDuDenCodeInsbesondereDieIfBlöckeVielleichtEinrücken,
da das die Lesbarkeit deines Codes stark erhöhen würde?
mfg mf

PS: JAL, etwas schlimmeres hab ich noch nie gesehen. Welche Vorteile hat 
JAL z.B. gegenüber C oder diversen Basic-Dialekten?

von Programist (Gast)


Lesenswert?

Mini Float schrieb:
> Welche Vorteile hat
>
> JAL z.B. gegenüber C oder diversen Basic-Dialekten?

Zuersmal ist das frei! Und ausserdem macht es einen assembler Code der 
kompatibel zu Mplab ist.Also kann man dann noch die Feinheiten in 
assembler programieren.

Aber keine Version der Pinmodifizierung hat funkzioniert. Der Compiler 
hat's nicht übersetzt.

Ich möchte den Code so ändern, dass die Pins frei wählbar sind so änlich 
wie hier:

-- var volatile bit enc_A is pin_d2
-- pin_d2_direction = input
-- var volatile bit enc_B is pin_d3
-- pin_d3_direction = input

von Programist (Gast)


Lesenswert?

Hier ist noch ein Beispiel wei er verwendet wird:
1
procedure eval_enc is
2
 var byte enc_var
3
 enc_var = 0
4
 enc_var = ReadEncoder (5)
5
6
if enc_var > 5 then  -- nach rechts drehen
7
 -- do comething
8
end if
9
 if enc_var < 5 then  -- nach links
10
 -- do comething 
11
end if
12
13
end procedure

Vielleicht braucht's jemand

von Rudi D. (rulixa)


Lesenswert?

Wenn Jal auch Assembler kann sieh mal hier
http://elektronik-labor.de/AVR/DDSGenerator.htm

von Programist (Gast)


Lesenswert?

Das ist ein anderer assembler.

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Aber keine Version der Pinmodifizierung hat funkzioniert. Der Compiler
> hat's nicht übersetzt.

Dazu zwei Fragen:
- Welche Werte hast Du für DeinPort, PinAufDemPort, DeinAndererPort und 
PinAufDemAnderenPort eingesetzt?

- Was meldet Dein Compiler dazu?

von Programist (Gast)


Lesenswert?

Das Problem war in dieser Zeile:

(DeinAndererPort >> (PinAufDemAnderenPort - 1))
So geht's nicht, es muss so sein (DeinAndererPort >> 
PinAufDemAnderenPort) sonst versteht der Coppiler das nicht.Ausserdem 
warum ist da ein or  "|"? da muss doch ein and  "&" hin.Sonst macht's 
keinen Sinn.Für mich auf jeden Fall.

Für die Pins habe Ich die gleichen probiert.Also pin 2 und 3 auf dem 
PORTD.

Mit der Methode hat es teilweise funktioniert aber nicht mit den 
gleichen Pins.Das geh't vermutlich nur wenn die Pins auf verschiedenen 
Ports sind.
EncoderValue = (((PORTA >> 5) & 0b00000010) | ((PORTC >> 4) & 
0b00000001))

Aou jeden Fall macht's keinen Sinn, denn man muss viel zu viel überlegen 
beim Zuweisen der Pins.Nnd das muss einfacher gehen.

von Programist (Gast)


Lesenswert?

So sieht es in assembler aus nach dem compilieren.
1
;; 027 :     EncoderValue = ((PORTD >> 2) & 0b00000011)
2
  movf    H'F83',w
3
  movwf   H'05C'
4
  movlw   H'02'
5
  movwf   H'05D'
6
  call    _4379__vector
7
  ;a2nd   _4379__vector
8
  movwf   H'057'
9
  movf    H'057',w
10
  andlw   H'03'
11
  movwf   H'055'
12
13
14
;; 044 :    operator >> ( byte in a, byte in n ) return byte is   
15
; var H'05C:000' a
16
; var H'05D:000' n
17
p_4379_shift_right: ; 24BE
18
  movwf   H'05D'
19
20
;; 045 :       while n > 0 loop   
21
w_4418_ag: ; 24BF
22
  movf    H'05D',w
23
  sublw   H'00'
24
  btfsc   H'FD8',0
25
w_4418_jb: ; 24C2
26
  goto    w_4418_be
27
  ;a2nd   w_4418_be
28
w_4418_bo: ; 24C4
29
30
;; 046 :          asm      clrc   
31
  clrc    
32
33
;; 047 :          asm rrf  a,f   
34
  rrf     H'05C',f
35
36
;; 048 :          n = n - 1   
37
  movlw   H'01'
38
  subwf   H'05D',w
39
  movwf   H'05D'
40
  goto    w_4418_ag
41
  ;a2nd   w_4418_ag
42
w_4418_be: ; 24CB
43
44
;; 050 :       return a   
45
  movf    H'05C',w
46
e_4379_shift_right: ; 24CC
47
  return

Da sieht man das da ziemlich viel passiert und es ist nicht leicht 
durchzuschauen.
Aber wenn man genug Zeit investiert, dann vielleicht kommt man drauf.

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Das Problem war in dieser Zeile:
>
> (DeinAndererPort >> (PinAufDemAnderenPort - 1))
> So geht's nicht, es muss so sein (DeinAndererPort >>
> PinAufDemAnderenPort) sonst versteht der Coppiler das nicht.

Damit wir nicht aneinander vorbeireden:
Mit "PinAufDemAnderenPort - 1" meine ich einen konstanten Ausdruck, den 
Du da einsetzen sollst. Wenn z.B. der eine Pin (A) Pin 5 auf auf PORTC 
ist, und der andere Pin (B) Pin 5 auf PORTD ist:

OldEncoderValue = ((PORTC >> 5) & 0b0000001) | ((PORTD >> 4) & 
0b00000010))

Falls B auf Pin 1 liegt, kannst Du den Shift-Operator auch weglassen, 
und wenn B auf Pin 0 liegt, musst Du stattdessen um 1 nach links 
schieben

OldEncoderValue = ((PORTC >> 5) & 0b0000001) | (PORTD & 0b00000010))
und
OldEncoderValue = ((PORTC >> 5) & 0b0000001) | ((PORTD << 1) & 
0b00000010))

Programist schrieb:
> Ausserdem
> warum ist da ein or  "|"? da muss doch ein and  "&" hin.Sonst macht's
> keinen Sinn.Für mich auf jeden Fall.

Das OR ist dafür da, die beiden Teilergebnisse zum Gesamtergebnis 
zusammenzufügen. Wenn die Pins direkt nebeneinander auf dem gleichen 
Port liegen, kannst Du darauf auch verzichten. Z.B.

OldEncoderValue = ((PORTD >> 5) & 0b00000011)

wenn die Pins auf 5 und 6 liegen.

von Programist (Gast)


Lesenswert?

Nun, O.K. aber wie kann man das einfacher machen?

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> Nun, O.K. aber wie kann man das einfacher machen?

Indem man z.B. bereits im Eröffnungspost angibt, um welchen Controller 
es sich handelt. Denn dann würden sich auch die Leute zu Wort melden, 
die mit PICs arbeiten und sich damit auskennen. Und es würden sich nicht 
die Leute verarscht vorkommen, die gern helfen würden, aber erst nach 
Recherche mitbekommen, dass Du mit PIC arbeitest.

Ich könnte Dir nun meine AVR-ASM-Routinen für Drehgeberabfrage posten, 
aber das nützt Dir ja beim PIC nichts.

...

von Programist (Gast)


Lesenswert?

Ja, stimmt.
Wie gesagt Ich arbeite mit PIC, genau mit dem PIC18F452.
Aber den Code kann man auch in andere Sprachen übersetzen, wenn man 
weiss wie.Man muss dazu nur verstehen wie das funktioniert.
Soviel Ich bis jetzt verstanden habe ist das hier "OldEncoderValue = 
((PORTD >> 2) & 0b00000011)" eine ganz nolmale valiable, aber Ich 
verstehe nicht wieso muss es so kompliziert berechnet verden?Wieso kann 
man da nicht einfach ein Wert zuweisen z.B "OldEncoderValue = 25" oder 
so ähnlich.

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Soviel Ich bis jetzt verstanden habe ist das hier "OldEncoderValue =
> ((PORTD >> 2) & 0b00000011)" eine ganz nolmale valiable, ..

Nein, das ist eine Zuweisung zu einer Variable, und das, was zugewiesen 
wird, ist keine Konstante, sondern der Input aus einem Eingabeport.

> .. aber Ich
> verstehe nicht wieso muss es so kompliziert berechnet verden?Wieso kann
> man da nicht einfach ein Wert zuweisen z.B "OldEncoderValue = 25" oder
> so ähnlich.

PORTD ist keine normale Variable, sondern lässt den Compiler Code 
erzeugen, der Den Eingabeport D einliest. Der Wert von PORTD entspricht 
also den logischen Spannungspegeln an den 8 Pins, die im Datenblatt 
unter Port D zusammengefasst sind.

Da ich PIC-Assembler nicht kenne, schreibe ich mal eine Art Pseudo-Code:

- lese Port D nach Register X (Das ist die Stelle, an der der Drehgeber 
seinen Status an Dein Programm übergibt.)
- schiebe Register X um 2 Stellen nach rechts (aus 10001100 wird 
00100011)
- Register X = Register X UND 00000011 (Maskiere irrelevante Bits aus)
- schreibe Register X nach Speicherstelle OldEncoderValue

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> Soviel Ich bis jetzt verstanden habe ist das hier "OldEncoderValue =
> ((PORTD >> 2) & 0b00000011)" eine ganz nolmale valiable, aber Ich
> verstehe nicht wieso muss es so kompliziert berechnet verden?Wieso kann
> man da nicht einfach ein Wert zuweisen z.B "OldEncoderValue = 25" oder
> so ähnlich.

Ich habe keine Ahnung von PICs, auch nicht von Hochsprachen, bei denen 
die Bitmanipulationen etwas kryptisch ausfallen, aber:

Wenn ich (handbetätigte) Drehgeber auswerten muss, dann interessieren 
mich die Änderungen der Zustände an den Pins. Um Änderungen zu erkennen, 
muss man den aktuellen Wert (Bitmuster) des Drehgeberzustandes (2 Bit, 
da 2 Eingänge für die beiden Kontaktspuren des Drehgebers) mit dem 
vorherigen Wert (Bitmuster der letzten Abtastung) vergleichen.

Dies macht man in einer Routine, die man in regelmäßigen Zeitabständen 
von z.B. 1 ms aufruft, am besten im Timer-Interrupt oder von einem Timer 
synchronisiert in einem Job der Mainloop.

In dieser Routine bastelt man sich eine Variable, die aus 2 Bit des 
aktuellen Zustandes und 2 Bit des vorherigen Zustandes (old) besteht und 
nutzt dabei zweckmäßigerweise die unteren 4 Bit der Variable. Diese wird 
dann als Index auf ein Array (mit Konstanten im Flash) benutzt, das 16 
Elemente enthält, in denen die Increment-Werte eingetragen sind. In die 
Flanken, die bei der einen Drehrichtung auftreten können, wird 1 
eingetragen, in die Flanken, die bei der Gegenrichtung auftreten, wird 
-1 eingetragen. In alle übrigen Elemente wird 0 eingetragen.

Anhand des Index, der ja aus altem und neuem Zustand der Drehgeberbits 
besteht, wird also bei Rechtsdrehung als Increment-Wert eine 1 
ermittelt, bei Linksdrehung eine -1 und bei keiner Drehung oder 
verbotenen Bitwechseln eine 0. Diese wird dann einfach zum momentanen 
Zählwert dazu addiert.

Hier mal zur Anschauung das Array in AVR-Assembler:
1
dgtab:      ;Tabelle mit Drehgeber-Werten (alt-alt-neu-neu als Index)
2
                    ;aa nn,     aa nn
3
.db     0, 0        ;00 00,     00 01
4
.db     1, 0        ;00 10,     00 11
5
.db     0, 0        ;01 00,     01 01
6
.db     0,-1        ;01 10,     01 11
7
.db    -1, 0        ;10 00,     10 01
8
.db     0, 0        ;10 10,     10 11
9
.db     0, 1        ;11 00,     11 01
10
.db     0, 0        ;11 10,     11 11
Die Kommentare (hinter den Semikolons ";") bilden den Index als 
Kombination der Bitmuster alt und neu ab. Es sind immer 2 Werte pro 
Zeile eingetragen, um die Konventionen einzuhalten (geradzahlige Anzahl 
Bytes pro Zeile aufgrund der 16-Bit-Adressierung des Flash beim AVR).

Und hier noch ein Auszug aus der Drehgeber-Abfrage, die alle 1 ms per 
Timer aufgerufen wird:
1
drehgeber:          ;wertet Drehgeberbewegungen aus
2
 in wl,dgpin                ;Drehgeber-Port einlesen
3
 andi wl,dgneumsk           ;nur die benutzten Bits werten
4
 lsl dgalt                  ;altes Drehgeber-Bitmuster
5
 lsl dgalt                  ;nach oben schieben
6
 or dgalt,wl                ;neue Drehgeberbits einblenden
7
 andi dgalt,dgaltmsk        ;Index begrenzen (uralt löschen) 
8
 ldi zl,low(dgtab*2)        ;Tabelle mit
9
 ldi zh,high(dgtab*2)       ;Dregheber-Increment-Werten
10
 add zl,dgalt               ;Index aufaddieren
11
 adc zh,null                ;Übertrag, falls Tabelle über Seitengrenze geht
12
 lpm wl,z                   ;Inkrement-Wert holen (0, +1 oder -1)
13
 ;in wl steht das Drehgeber-Inkrement, das die Drehrichtung angibt
14
 add dgz,wl                 ;Drehgeber-Increment aufaddieren
15
 ;dgz wurde nun erhöht, vermindert oder blieb unverändert
Diese Routine geht davon aus, dass der Drehgeber an Bit 0 und 1 des 
Ports angeschlossen ist. Bei anderen Anschluss-Belegungen müssen die 
Bits eben anders zusammengesammelt werden, aber immer so, dass alt und 
neu zusammenhängend in den unteren 4 Bit landen. Denn diese 4 Bits aus 
altem und neuen Zustand werden ja als Index auf die Increment-Tabelle 
(Array) benutzt. Werden die Bits im Index anders angeordnet, dann muss 
natürlich die Tabelle auch anders mit Werten gefüllt werden.

Wie Du siehst, geht es hier um einzelne Bits des alten und neuen 
Drehgeberstaus, die zu einem Index zusammengebastelt werden. Da wird das 
nichts, mal einfach "OldEncoderValue = 25" oder so zu schreiben... ;-)

...

von Programist (Gast)


Lesenswert?

Philipp Klostermann schrieb:
> - lese Port D nach Register X (Das ist die Stelle, an der der Drehgeber
>
> seinen Status an Dein Programm übergibt.)
>
> - schiebe Register X um 2 Stellen nach rechts (aus 10001100 wird
>
> 00100011)
>
> - Register X = Register X UND 00000011 (Maskiere irrelevante Bits aus)
>
> - schreibe Register X nach Speicherstelle OldEncoderValue


Und wenn wir das getan haben, dann haben wir eine Zahl 00000011 in 
unserem
Register X. Und das ist 3 dezimal.Ihr meint also das diese Zahl sich 
ständig ändert, aber das ist nicht so, weil diese Variable am Anfang des 
Programs ist und nicht im main loop.Sie wird also nur einmal berechnet.

von Programist (Gast)


Lesenswert?

Oder doch "OldEncoderValue = EncoderValue"  -- hier wird sie neu 
geschrieben, aber am Anfang, also hier

var byte OldEncoderValue
OldEncoderValue = ((PORTD >> 2) & 0b00000011)

kann man genauso gut OldEncoderValue = 3 schreiben

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> kann man genauso gut OldEncoderValue = 3 schreiben

Nein. Denn der eigentliche Wert hängt vom Portzustand, also der Stellung 
des Drehgebers ab.

...

von Loonix (Gast)


Lesenswert?

Programist schrieb:
> ((PORTD >> 2) & 0b00000011)

Dieser Ausdruck kann 4 verschiedene Zahlen als Ergebnis bringen:

0,1,2,3

Einverstanden?

von Programist (Gast)


Lesenswert?

Sehen wir uns das genauer an

var byte OldEncoderValue
OldEncoderValue = ((PORTD >> 2) & 0b00000011)

Da wird eine Variable deklariert und berechnet.

Und dann wird diese variable im Laufe des Programms verändert

am Ende aber wird sie wieder hergestellt "OldEncoderValue = 
EncoderValue"

und die Variable "EncoderValue" ist die gleiche.

var byte EncoderValue
EncoderValue = ((PORTD >> 2) & 0b00000011)

von bitte löschen (Gast)


Lesenswert?

Wenn die Variable OldEncoderValue am Anfang nicht mit den tatsächlichen 
Bitwerten, die an den Pins anliegen, sondern mit einem konstanten Wert 
initialisiert wird, und dann beim ersten Aufruf der Funktion ReadEncoder 
mit den tatsächlichen Werten verglichen wird, wird beim Start (mit der 
Wahrscheinlichkeit 3:1) eine Bewegung gemeldet, die gar nicht eingegeben 
wurde.

Wenn Du das nicht verstehst, solltest Du Dir mal überlegen, ob Radfahren 
oder Kino nicht auch schöne Hobbys sind. ;-)

Nachtrag:
Den Code in Deinem Eingangsposting empfinde ich übrigens als 
umständliche und unleserliche Frunzelei. Ich glaube zwar nicht, dass das 
an Jal liegt, aber unabhängig davon solltest Du als Anfänger vielleicht 
überlegen, ob Du nicht mit einer bekannteren Programmiersprache (wie C 
oder Assembler) anfangen willst. Sich mit solchen Exoten zu beschäftigen 
ist üblicherweise die Sache von Nerds, die Spaß daran haben, sich ohne 
sittlichen Nährwert in so einen Kram zu vertiefen.

von Programist (Gast)


Lesenswert?

Ich sehe jetzt, dass das es komplizierter ist als ich gedacht habe.
Hie habe Ich noch ein anderes Beispiel
1
pin_a0_direction = input
2
pin_a1_direction = input
3
4
var bit rotary_a, rotary_b
5
6
procedure enc_right is
7
-- Do something when knob is moved clockwise
8
end procedure
9
10
procedure enc_left is
11
-- Do something when knob is moved counter-clockwise
12
end procedure
13
14
15
forever loop
16
rotary_a = pin_a0
17
rotary_b = pin_a1
18
while ( pin_a0 == rotary_a ) & ( pin_a1 == rotary_b ) loop
19
-- Do nothing until knob is turned
20
end loop
21
if pin_a0 ^ rotary_b then
22
enc_right
23
end if
24
if pin_a1 ^ rotary_a then
25
enc_left
26
end if
27
delay_1ms( 3 )
28
end loop

Hier ist das einfacher.Velche version ist besser?

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Hier ist das einfacher.Velche version ist besser?

Erstmal die, die Du besser verstehen kannst.

von Programist (Gast)


Lesenswert?

Die zweite kann Ich besser verstehen.

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> Hier ist das einfacher.Velche version ist besser?

Gut (für Dich) ist nur die Routine, die Du verstehst und die Du souverän 
an andere Bedingungen anpassen kannst. Die zuletzt angepriesene Routine 
ist schon alleine deshalb nicht gut, weil sie mit Wartezeiten (Takte 
zählen) im Millisekunden-Bereich (tausende Takte bereich) arbeitet:

> delay_1ms( 3 )

Sowas macht man nicht, denn eine Drehgeber-Abfrage ist kein Selbstzweck, 
sondern nur ein klitzekleiner Teil eines größeren Programms. Und sowas 
programmiert man nunmal so, dass es im Hintergrund läuft und andere 
Teile des Programms nicht blockiert.

Ich habe Dir hier Beitrag "Re: Drehgeber code"
(m)einen Algorithmus zur Drehgeberabfrage vorgestellt und erklärt.

- Hast Du Dir das wenigstens mal angesehen?

- Hast Du mal versucht, den Algorithmus zu verstehen?

- Hast Du mal versucht, den Algorithmus in der Programmiersprache,
  mit der Du Dich als "Programmist" auskennst, umzusetzen?

Vermutlich nicht, Du suchst Dir irgendwelche halbseidenen "Beispiele" 
aus dem Netz zusammen und stellst sie hier nach Quizmasterart (*) zur 
Diskussion.

Mach's doch wie Andere, verwende Deinen eigenen Code. Und solange Du es 
noch nicht schaffst, hocheffizienten eigenen Code zu schreiben, musst Du 
es eben etwas einfacher und übersichtlicher (mit Zwischenschritten) 
formulieren. Hauptsache Du verstehst ihn (Deinen Code) und er tut das, 
was Du willst. Fremden unverstandenen Programmcode verwendet man 
grundsätzlich nicht, nicht als Hobby-Programmierer und erst recht nicht 
als Programmist.

...

(*) Quizmaster:
> Sehen wir uns das genauer an
> Hie habe Ich noch ein anderes Beispiel

von bitte löschen (Gast)


Lesenswert?

Hannes Lux schrieb:
> Fremden unverstandenen Programmcode verwendet man
> grundsätzlich nicht, nicht als Hobby-Programmierer und erst recht nicht
> als Programmist.

So ganz verallgemeinern würde ich das nicht. Ich habe z.B. mal die 
Sourcen der JPEG-6 Library in meinen Kram übernommen, indem ich von den 
dort definierten structs eigene Klassen abgeleitet habe, ohne den C-Code 
der Library vollständig zu verstehen.
Aber: Bei so völlig trivialem Pupskram hier, den jedem Anfänger sofort 
einleuchten muss, weil er auf einer Ebene mit "LED an, LED aus" steht, 
stimme ich zu.

Sorry Programmist, aber wenn Du damit Probleme hast, hast Du entweder 
etwas völlig falsch verstanden, oder.. Ach ja, im Café sitzen ist auch 
noch ein schönes Hobby.

von Peter D. (peda)


Lesenswert?

Viele MCs können direkt IO-Pins testen. Dann braucht man nicht 
umständlich schieben und maskieren und ist völlig frei in der Wahl der 
Pins, sie können sogar auf verschiedenen Ports liegen
Und wenn man dabei gleich den Gray-Code in Binär umwandelt, spart man 
sich auch noch den Tabellenzugriff.

Hier ein Beispiel:

http://www.mikrocontroller.net/articles/Drehgeber#Solide_L.C3.B6sung:_Beispielcode_in_C


Peter

von Programist (Gast)


Lesenswert?

Hannes Lux schrieb:
> Ich habe Dir hier Beitrag "Re: Drehgeber code"
>
> (m)einen Algorithmus zur Drehgeberabfrage vorgestellt und erklärt.
>
>
>
> - Hast Du Dir das wenigstens mal angesehen?
>
>
>
> - Hast Du mal versucht, den Algorithmus zu verstehen?
>
>
>
> - Hast Du mal versucht, den Algorithmus in der Programmiersprache,
>
>   mit der Du Dich als "Programmist" auskennst, umzusetzen?

Ja, Ich habe mir das angesehen, aber das ist noch ein bischen zu 
kompliziert für mich.Ich muss noch Erfahrungen sammeln.Aber Ich habe 
schon was gelernt in dieser Zeit.
Ihr habt mehr Erfahrung, deswegen frage ich auch.Ich kann natürlich 
selber versuchen das Problem zu lösen, aber das wird länger dauern.Aus 
diesem Grund wollte Ich Leute fragen die mehr drauf haben als Ich.

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> Ihr habt mehr Erfahrung, deswegen frage ich auch.

Diese Erfahrung hat uns aber keiner in die Wiege gelegt, die mussten wir 
uns selbst aneignen, was viel Zeit, Fleiß und Ausdauer gekostet hat.

> Ich kann natürlich
> selber versuchen das Problem zu lösen,

Da wirst Du nicht drumherum kommen. Von nichts kommt nichts.

>  aber das wird länger dauern.

Dafür hast Du dann aber den Lerneffekt. Und je öfter Du den hast, umso 
leichter wird Dir die nächste Problemlösung fallen. Wir mussten diese 
Zeit auch investieren.

> Aus
> diesem Grund wollte Ich Leute fragen die mehr drauf haben als Ich.

Das ist dann legitim, wenn Du mal einen Hinweis brauchst, also einen 
Schubs in die richtige Richtung.

Bitter nötiges Grundwissen kannst Du damit aber nicht erwerben, das 
musst Du Dir schon selbst erarbeiten. Wenn man mit Mikrocontrollern 
arbeiten will, ist es kein Schaden, Selbstverständlichkeiten wie z.B. 
die logischen Grundfunktionen (AND, OR, EXOR) genauso zu beherrschen wie 
das kleine Einmaleins. Das kann man Dir aber nicht durch ein 
quizähnliches Ratespiel hier im Forum vermitteln, da musst Du schon mal 
selbst etwas tun (Wahrheitstabellen analysieren usw.).

Gerade bei diesen logischen Verknüpfungen scheint es bei Dir zu hapern, 
denn sonst kämst Du nicht auf die Idee, dass ein eingelesener 
Port-Zustand (variabler Wert, Wertebereich 0 bis 255), um 2 
Bitpositionen nach rechts geshiftet (Wertebereich jetzt 0 bis 63) und 
mit 3 AND-verknüpft (Wertebereich jetzt 0 bis 3) dasselbe sei wie 3.
Mensch, das ist Grundwissen der Digitaltechnik, ohne dies bist Du 
betreffs Mikrocontroller-Programmierung aufgeschmissen, egal welche 
Programmiersprache Du benutzt.

Wenn Du einen guten präzisen Drehgeber hast, dann schau Dir mal den Code 
von Peter Dannegger an. Von Peter kommt nur hocheffizienter, sorgfältig 
erarbeiteter Programmcode, der garantiert fehlerfrei läuft.

Da ich aber viel mit Drehgebern von Pollin gebastelt habe, die den 
Rastpunkt genau auf der Flanke einer Spur haben, war dieser Code (für 
mich und diese speziellen Drehgeber) nicht optimal. Daher schrieb ich 
mir den oben vorgestellten eigenen Code (mit Tabelle), denn der kommt 
mit diesen unsauber arbeitenden Pollin-Drehgebern gut zurecht. Und er 
ist so flexibel, dass man ihn (wenn man ihn verseht) leicht an andere 
Drehgeber (betreffs Impulse pro Rastung) anpassen kann, indem man 
einfach die Tabelle ändert. Auch Anpassung an andere Portpins ist 
möglich, da müssen eben die Bits anders zusammengewürfelt werden. Ich 
habe da auch eine Variante im Einsatz, die in einem Byte die Bits von 2 
Drehgebern verwaltet (jedes Nibble ein Drehgeber).

...

von bitte löschen (Gast)


Lesenswert?

Lieber Programmist!

Ich bin auch einer, der gerne Dinge überstürzt und sich lieber ein 
eigenes und möglichst exotisches Einsteigerprojekt auswählt, anstatt ein 
Beispiel aus einem Tutorial nachzuvollziehen, wenn ich mich mit etwas 
neuem beschäftige, insofern kann ich Dich gut verstehen.

Bei mir geht das meistens tendenziell so: Ich stoße durch Zufall auf ein 
neues Gebiet, suche nach einführenden Informationen und fange an, mich 
da einzulesen. Während des Lesens tanzt meine Phantasie dann nebenbei 
Break Dance und verknüft die aufgenommenen Informationen dergestalt, 
dass verrückte Projektideen heraus sprudeln. Das führt dann schnell 
dazu, dass ich mich kaum mehr auf den (meist zu ausführlichen und in 
Teilen redundanten) Text konzentrieren kann, und anfange quer zu lesen, 
um die Lücken, die eine direkte Umsetzung verhindern, möglichst schnell 
zu schließen. Bei der Umsetzung stoße ich natürlich auf einen Haufen 
Probleme, da noch viele unentdeckte Lücken existieren, und der Teufel 
immer im Detail steckt. Diese Lücken recherchiere ich dann, und langsam 
fügt sich das Puzzle zusammen. Das ist kein leichter Weg. Eigentlich 
führt er langsamer zum Ziel, als z.B. den Code in einem Tutorial zu 
verstehen, abzutippen und auszuprobieren, aber dieser Weg hat den 
Vorteil, dass man, sobald man das Tutorial (oft nach wenigen Absätzen) 
verlassen hat, und nun Handbücher nach bestimmten Informationen 
durchblättert, viele Details, die zu dem Zeitpunkt noch irrelevant 
scheinen, nebenbei mit aufnimmt, und sie später zur Verfügung hat. Das 
ganze macht mir Spaß. Ich liebe es, mich mit chinesischem Englisch zu 
quälen und jeder Misserfolg ist für mich ein Erfolg, sobald ich dadurch 
etwas lernen konnte.
Dabei muss ich selten Fragen in einem Forum stellen, weil Foren 
üblicherweise eine Suchfunktion haben, und die meisten Fragen irgendwann 
schon mal gestellt wurden. Wenn ich doch mal frage, dann weil ich eine 
Frage interessant finde, z.B. wenn etwas funktioniert, von dem ich 
erwartrt hätte, dass es nicht funktioniert, und gerne die Meinung 
anderer hören würde.

Irgendwie drängt sich mir der Eindruck auf, dass Du den ersten Schritt, 
nämlich die ersten Absätze eines Tutorials zu lesen, weggelassen hast, 
denn Du hast eine Programmiersprache gewählt, die in keinem mir 
bekannten µC-Tutorial als Beispiel-Sprache dient.

Dir fehlen die grundlegenden Konzepte der Programmierung. (Da hatte ich 
in Bezug auf µCs den Vorteil, dass ich seit 25 Jahren in verschiedenen 
Sprachen programmiere, und mich als Kind mal ein wenig mit Elektronik 
beschäftigt habe. - Ein Physikbuch in der Schulmülltonne war schuld.)

Mein ernst gemeinter Ratschlag:
Fange mit Atmel µCs (AVRs) an, denn für die existiert hier auf 
mikrocontroller.net ein tolles Tutorial: Klicke ganz oben links auf 
"AVR" und dann auf "AVR-Tutorial" (oder auf diesen Link: 
http://www.mikrocontroller.net/articles/AVR-Tutorial)
Der Rest gibt sich dann von ganz alleine.
Später kommt dann noch die Sprache C dazu. Mit C lernst Du viele 
Syntax-Elemente, die es auch in anderen Sprachen gibt, so dass Du keine 
neue Sprache lernen musst, um ein kleines Jal-Listing zu lesen und zu 
verstehen.
Mit C lernst Du auch Konzepte wie Funktionen und Parameter, lokale und 
globale Variablen, Zeiger, Speicherverwaltung, Stack, usw.. kennen, und 
wirst in der Lage sein, sie in Deinen Programmen richtig anzuwenden.

Ob Du diesen Rat befolgst, oder nicht, eines ist gewiss: Du wirst Dich 
immer wieder durchbeißen müssen. So viele Fragen, wie haben wirst, kann 
man gar nicht in einem Forum stellen. Die meisten werden deutlich 
komplizierter sein, als das Thema dieses Threads, und Du wirst ihre 
Antworten selber herausfinden müssen.

Der Weg ist das Ziel. (Abgedroschen, aber soo wahr!)

von Programist (Gast)


Lesenswert?

Lieber Philipp Klostermann,

Da liegst du falsch.Mir fehlen keine grundlegenden Konzepte der 
Programierung.
Ich habe schon viele Sachen selber programiert.Bei diesem spezielem Fall 
kenne Ich mich leider nicht so gut aus.Die Programierung hier ist auch 
schwierig weil sie von der Hardware abhängig ist, also von dem 
eingesetzten Encoder.Und den Code muss man dan testen an realer 
Hardware.
Deswegen wollte Ich hier auf fertige Lösungen zugreifen.

von Programist (Gast)


Lesenswert?

Und wenn Ich was nicht verstehe dann kann Ich immer nachschauen Z.B hier

http://www.chemgapedia.de/vsengine/vlu/vsc/de/ch/11/cmt/vlus/pic_programm.vlu/Page/vsc/de/ch/11/cmt/grundlagen/pichtml/befehle/andlw.vscml.html

Da wird's erklärt was die einzelnen Befehle tun.Da hat jemand gesagt er 
kann kein Pic assembler.Da kann mam das lernen.Ihr habt selber keine 
Ahnung.Ich habe eine ganz eifach Frage gestellt, nämlich wie kann man 
den Code so ändern das die Pins frei wählbar sind und ihr mir mit einer 
Behlerung über meine Programierkenntnisse.Was soll das?

von Hannes L. (hannes)


Lesenswert?

Programist schrieb:
> Und wenn Ich was nicht verstehe dann kann Ich immer nachschauen Z.B hier
>
> 
http://www.chemgapedia.de/vsengine/vlu/vsc/de/ch/11/cmt/vlus/pic_programm.vlu/Page/vsc/de/ch/11/cmt/grundlagen/pichtml/befehle/andlw.vscml.html
>
> Da wird's erklärt was die einzelnen Befehle tun.Da hat jemand gesagt er
> kann kein Pic assembler.

Ja, hier, ich z.B. kann kein PIC-Assembler.

> Da kann mam das lernen.

Warum sollte ich das tun??? Ich mache nichts mit PICs. Ich bastele mit 
AVRs. Und mit denen komme ich so zurecht, dass ich darauf verzichten 
kann, andere Leute z.B. in Foren zu fragen. Nein, ich bin kein Meister 
der Programmierung, meine aber doch, dass ich souverän mit den AVRs 
umgehen kann.

> Ihr habt selber keine
> Ahnung.

Stimmt, jetzt wo Du es sagst. Dafür komme ich mit meinen AVRs aber 
erstaunlich gut und auch ohne fremde Hilfe zurecht.

> Ich habe eine ganz eifach Frage gestellt, nämlich wie kann man
> den Code so ändern das die Pins frei wählbar sind

Soooo ei(n)fach ist diese Frage aber gar nicht... Dabei hast Du nämlich 
nichtmal verstanden, wie die Drehgeber-Bits (aktuell und old) in die 
"Variable" kommen. Hättest Du dies verstanden, dann wäre es Dir ein 
Leichtes, die Bits mittels der in Deinem Controller verfügbaren 
Möglichkeiten dahin zu transferieren, wo Du sie brauchst. Beim AVR wäre 
das im ungünstigsten Fall, also wenn es mit Schieben, MOV, AND und OR zu 
umständlich wird, über das T-Flag (BST/BLD).

> und ihr mir mit einer
> Behlerung über meine Programierkenntnisse.

Ich habe mit Mühe gegeben Dir zu helfen. Es tut mir zwar jetzt etwas 
leid um die verschwendete Zeit, aber ich werde es vermutlich wieder tun, 
wenn jemand Hilfe braucht und die helfenden Antworten von Anderen noch 
nicht gegeben wurden. Den von mir verwendeten Algorithmus kann man 
übrigens auch anhand der Kommentare nachvollziehen, ohne in AVR-ASM 
perfekt zu sein.
Du wirfst den Helfern vor, dass sie kein PIC-ASM lernen wollen, dabei 
bist Du (als Hilfesuchender) selbst nicht bereit, mal ein paar 
AVR-ASM-Befehle nachzuschlagen, um mein Beispiel besser verstehen zu 
können.

> Was soll das?

Das frage ich mich auch. Trotzdem wünsche ich Dir noch viel Spaß beim 
Hobby und auch viel Erfolg dabei.

...

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Da liegst du falsch.Mir fehlen keine grundlegenden Konzepte der
> Programierung.

Ansichtssache. Ein junger Führerscheinneuling wird auch der Meinung 
sein, er könne Auto fahren, und wird widersprechen, wenn ein erfahrener 
Autofahrer ihn darüber informiert, dass dem nicht so ist. Nur weil er in 
der Lage ist, ein Fahrzeug zu steuern (oder durch Kurven rutschen zu 
lassen), kann er noch lange nicht wirklich Auto fahren.

> Ich habe schon viele Sachen selber programiert.Bei diesem spezielem Fall
> kenne Ich mich leider nicht so gut aus.

Das ist eine Aussage wie: "Ich bin schon viele Strecken gefahren, aber 
mit dieser Kreuzung kenne ich mich leider nicht so gut aus."
Das, was Du einen "speziellen Fall" nennst, ist selbst für jemanden, der 
Jal nicht kennt eine völlig triviale Kleinigkeit. Kein Programmierer 
wird Dir abnehmen, Du hättest Programmierkenntnisse, wenn Du damit 
Probleme hast.

> Die Programierung hier ist auch
> schwierig weil sie von der Hardware abhängig ist, also von dem
> eingesetzten Encoder.

Bu....it! Der Encoder liefert binäre Informationen auf 2 Leitungen, auf 
Änderungen wird reagiert. Daran ist rein gar nichts schwierig. Wenn sich 
die Dir bekannten Encoder in diesem Punkt unterscheiden, wirst Du uns 
doch sicher mindestens 2 Modelle mit unterschiedlichem Verhalten und den 
von Dir verwendeten nennen können. Das wäre nett, sonst rätseln wir hier 
rum, und wissen nicht mal, worüber.

> Und den Code muss man dan testen an realer
> Hardware.

Das ist immer so. Hast Du schon so etwas: 
http://www.reichelt.de/Laborkarten/STECKBOARD-1K2V/index.html?ACTION=3&GROUPID=3374&ARTICLE=67678&SHOW=1&START=0&OFFSET=100&;PROVID=2402

> Deswegen wollte Ich hier auf fertige Lösungen zugreifen.

Programist schrieb:
> Da hat jemand gesagt er
> kann kein Pic assembler.Da kann mam das lernen.

Muss man aber nicht, wenn es um ein Listing in einer Programmiersprache 
geht. Es ist in Bezug auf Deine Aufgabe völlig wumpe, ob das für einen 
AVR oder PIC implementiert wird.

> Ihr habt selber keine
> Ahnung.

Stimmt. Z.B. von J2EE, von FPGAs, sizilianischen Bauerntrachten oder dem 
Goldman Sachs Commodity Index. :-D

> Ich habe eine ganz eifach Frage gestellt, nämlich wie kann man
> den Code so ändern das die Pins frei wählbar sind und ihr mir mit einer
> Behlerung über meine Programierkenntnisse.Was soll das?

Die Frage wurde Dir mehrfach beantwortet und Du hast die Antworten nicht 
verstanden. Wenn man dann das folgende liest, kann man daraus nur 
schlussfolgern, dass Du ein Programmieranfänger bist, der noch nicht 
einmal mit den Begrifflichkeiten zurechtkommt:

Programist schrieb:
> Soviel Ich bis jetzt verstanden habe ist das hier "OldEncoderValue =
> ((PORTD >> 2) & 0b00000011)" eine ganz nolmale valiable, ..

Etwas anderes:
Ich bin es ja gewohnt, dass man es in Foren mit Grammatik und 
Rechtschreibung nicht so genau nimmt, aber Deine Beiträge sind schon 
speziell. Deshalb frage ich mal ganz vorsichtig, ob Du Legastheniker 
bist oder Deutsch nicht Deine Muttersprache ist. Wenn ja, ist das OK und 
ich will nichts weiter dazu sagen. Ansonsten sei darauf hingewiesen, 
dass ich und sicher auch einige andere diese Nachlässigkeit als 
Respektlosigkeit empfinden. Wenn jemand eine Frage stellt, sollte er sie 
freundlicherweise so formulieren, dass sein Gegenüber nicht zu viel Mühe 
investieren muss, um sie überhaupt zu entziffern.

Programist schrieb im Beitrag #2216133:
> Du hältst dich für sehr schlau, aber glaub mir, du bist es nicht.

Schlau wäre es, hier nicht zu antworten und stattdessen die Zeit zu 
nutzen, Kohle zu machen. - Aber dazu fehlt mir die Schlauheit! :-D

von Programist (Gast)


Lesenswert?

Da hast du dir Mühe gemacht, das alles zu schreiben nur un mich zu 
reizen.
Aber Ich bin ein Yogi und habe durch Jahrelanges Training und Studium 
der antiken Schriften das geheime Wissen der absoluten 
Bewusstseinskontrolle erlangt.Also kann mich nichts und niemand aus der 
Fassung bringen.

von bitte löschen (Gast)


Lesenswert?

Programist schrieb:
> Da hast du dir Mühe gemacht, das alles zu schreiben nur un mich zu
> reizen.

Nein, Du tust mir nur noch leid - na ja, zur Hälfte. Zur anderen Hälfte 
finde ich Deine geistigen Ergüsse belustigend.

Programist schrieb:
> Aber Ich bin ein Yogi und habe durch Jahrelanges Training und Studium
> der antiken Schriften das geheime Wissen der absoluten
> Bewusstseinskontrolle erlangt.

Na sicher dat! lol

Philipp Klostermann schrieb:
> Wenn sich
> die Dir bekannten Encoder in diesem Punkt unterscheiden, wirst Du uns
> doch sicher mindestens 2 Modelle mit unterschiedlichem Verhalten und den
> von Dir verwendeten nennen können.

???

von Michael K. (Gast)


Lesenswert?

Programist schrieb:

> Und wenn Ich was nicht verstehe dann kann Ich immer nachschauen Z.B hier

Ja dann mach das doch.

> Da kann mam das lernen.

Ja dann mach das doch.

> Ihr habt selber keine Ahnung

Ach, jetzt frech werden? So wirst Du Dir ganz schnell Freunde machen, 
die Dir alle ganz unbedingt helfen wollen.

>Was soll das?

Das frage ich mich auch. Hier versucht man Dir zu helfen und Du wirst 
pampig.

von Michael K. (Gast)


Lesenswert?

Programist schrieb:
> Da hast du dir Mühe gemacht, das alles zu schreiben nur un mich zu
> reizen.
> Aber Ich bin ein Yogi und habe durch Jahrelanges Training und Studium
> der antiken Schriften das geheime Wissen der absoluten
> Bewusstseinskontrolle erlangt.Also kann mich nichts und niemand aus der
> Fassung bringen.

Sag doch gleich, daß Du ein Troll bist.

Aber ich muss zugeben, Du bist gut. Den etwas "dappigen" 
Programmieranfänger spielst Du ziemlich gut.

von bitte löschen (Gast)


Lesenswert?

Natürlich! Ein Troll! Manchmal sieht man den Wald vor lauter Bäumen 
nicht! :-D

Michael Krauth schrieb:
> Den etwas "dappigen"
> Programmieranfänger spielst Du ziemlich gut.

Also ich fand es etwas übertrieben. Ich habe mir immer wieder gedacht, 
dass eigentlich kein Mensch so dämlich sein kann. Hätte ich nicht schon 
ähnlich depperte Typen in der Realität erlebt, wäre ich schon früher von 
selbst darauf gekommen.

von Programist (Gast)


Lesenswert?

Ja, diesen Code hat jemand geschrieben der wusste was er tat.Er seht so 
einfach aus aber er hat's in sich.

von bitte löschen (Gast)


Lesenswert?

Bye Thread

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.