Forum: Mikrocontroller und Digitale Elektronik Arduino PIND funzt nicht


von key-board (Gast)


Lesenswert?

Hallo
Ich will einen Drehencoder auswerten mit nur einem Interruptpin. zur 
anzeige werden 2 LEDs angesteuert. bei Linksdrehung leuchtet die eine 
bei rechtsdrehung die andere

Mit
setup
...
attachInterrupt(0,ISR,RISING);
...
loop
...


void ISR()
{
  detachInterrupt(0);
   if (digitalRead(4)==HIGH)
{
digitalWrite(22,HIGH);
    digitalWrite(23,LOW);
    }
    else
    {
      digitalWrite(23,HIGH);
    digitalWrite(22,LOW);
      }
      attachInterrupt(0,ISR,RISING);
}
}

funzt es zwar aber mehr schlecht als recht. Die LEDs zittern mir zu viel 
sprich da sind false erkennungen dazwischen. Ich vermute es liegt an der 
digitalRead() Funktion  weil die  recht langsam ist.

Also direkte Portmanioulation
die IF bedingung ersetzt durch
if (PIND & B0001000==B00010000)

Beim Kompilieren keinen Fehler aber funzt nun garnicht mehr. zumindest 
leichtet egal welche richtung ich drehe nur die LED auf Pin 23 sprich 
die, wenn die Bedingung nicht erfüllt ist

seht ihr vielleicht was da falsch bei mir ist?
ist übrigens ein Arduino Mega

von cprog (Gast)


Lesenswert?

key-board schrieb:
> seht ihr vielleicht was da falsch bei mir ist?

Lass wenigstens mal die automatische Formatierung über deinen Code 
laufen. Dann sähe das schon viel übersichtlicher aus.

key-board schrieb:
> Ich vermute es liegt an der digitalRead() Funktion  weil die
> recht langsam ist.

So langsam ist die nun auch wieder nicht - kommt natürlich etwas auf die 
Prozessortaktfrequenz und die Pulsfrequenz vom Inkrementalgeber drauf 
an. Und wenn dein Geber prellt, kannst du mit Interruptsteuerung viel 
"Freude" haben.

von C-liker (Gast)


Lesenswert?

key-board schrieb:
> seht ihr vielleicht was da falsch bei mir ist?
Also erstens zind die Einrückungen eine Katastrophe, darum geht es jetzt 
aber nicht, und zweitens:

key-board schrieb:
> if (PIND & B0001000==B00010000)
Das Gleiche nochmal mit einem Zeilenumbruch, fällt dir was auf?
1
 
2
if (PIND & B0001000==
3
          B00010000)
Das kann gar nicht gleich sein.

Das ==B00010000 ist auch überflüssig, schreib einfach
if(PIND & B0001000) oder noch besser if(PIND & (1<<3))

von key-board (Gast)


Lesenswert?

sorry hab in Zeile
if (PIND & B0001000==B00010000)
einen Tippfehler
if (PIND & B00010000==B00010000)
muss es heißen

der fehler ist im code NICHT drin

von cprog (Gast)


Lesenswert?

key-board schrieb:
> der fehler ist im code NICHT drin

Warum zeigst du dann nicht deinen Code, sondern irgend etwas anderes?

von Max H. (hartl192)


Lesenswert?

key-board schrieb:
> sorry hab in Zeile
> if (PIND & B0001000==B00010000)
> einen Tippfehler
Womit wir schon beim nächsten Fehler sind: Quellcode nicht abtippen, 
copy 'n' paste oder als Anhang.

Sieh dir das mal an:
https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t
'==' hat höhere Priorität als das '&', setzt PIND & B0001000 in Klammern 
oder lass das ==B00010000 ganz weg.

Was sicher auch nicht schadet ist wenn du dir das entsprechende Kapitel 
im AVR-GCC-Tutorial anschaust:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Eing.C3.A4nge_.28Wie_kommen_Signale_in_den_.C2.B5C.29

: Bearbeitet durch User
von key-board (Gast)


Lesenswert?

ja das mit dem einrücken seh ich ein
dass sieht in meiner software schöner aus. (ordentlich eingerückt)

hab eure Nachichten erst gelesen als ich meine berichtigung abgeschikt 
habe.
Wie gesagt der Tippfehler ist im Code nicht mit drin.

@C-liker
die Varianten
if(PIND & (1<<5)) und (5 weil Input an Pin mit Nummer 4 PIND von 0 bis 7 
und da ist das pin 4 das 5. bit.)
if(PIND & B00010000)
hab ich auch schon beide probiert. nix geht... wie gesagt nehme ich 
digitalRead(4) funzt das ganze. Um das Prellen wollte ich mich kümmern 
wenn das mit PIND auch kein zufrieden stellendes Ergebniss bringt, aber 
die leds sollten zumindest hin und her flackern wenn der encoder prellt. 
das tun sie bei digitalRead ja auch, aber es passiert ja nix... leuchtet 
nur stuhr die LED welche im else zweig gesetzt wird.

von Max H. (hartl192)


Lesenswert?

key-board schrieb:
> if(PIND & (1<<5)) und (5 weil Input an Pin mit Nummer 4 PIND von 0 bis 7
> und da ist das pin 4 das 5. bit.)
> if(PIND & B00010000)
Das stimmt jetzt aber nicht zusammen;
(1<<5) = B0010'0000 zum vergleich
  PIND & B0001'0000

Welchen Arduino hast du eigentlich?

von key-board (Gast)


Lesenswert?

void setup() {
  // put your setup code here, to run once:
pinMode (4,INPUT);
pinMode (3,INPUT);
pinMode (2,INPUT);
pinMode (22,OUTPUT);
pinMode (23,OUTPUT);
attachInterrupt(0,dir,RISING);
attachInterrupt(1,off,RISING);

}
byte x=0;
void loop() {
  // put your main code here, to run repeatedly:

}


void dir()
{
  detachInterrupt(0);

  if((PIND & B0001000))
  {
    digitalWrite(22,HIGH);
    digitalWrite(23,LOW);
    }
    else
    {
      digitalWrite(23,HIGH);
    digitalWrite(22,LOW);
      }
      attachInterrupt(0,dir,RISING);
  }

  void off()
  {
    digitalWrite(23,LOW);
    digitalWrite(22,LOW);
    }

so hier der komplette code :) mit den letzten änderungsvorschlägen aber 
immer noch... nur LED auf Pin 23 leuchtet egal in welche Richtung ich 
drehe :(

von Max H. (hartl192)


Lesenswert?

Max H. schrieb:
> Welchen Arduino hast du eigentlich?
Sry, ich hab's überlesen, ist der "Arduino Mega"

von key-board (Gast)


Lesenswert?

boar jetzt hatte ich schonwieder den "tippfehler" drin da ich den 
vorschlag aus
"'==' hat höhere Priorität als das '&', setzt PIND & B0001000 in 
Klammern
oder lass das ==B00010000 ganz weg.
"
einfach übernommen hatte... aber auch berichtigt gehts nicht:(
Exakt ist es der SainSmart MEGA 2560

von Max H. (hartl192)


Lesenswert?

Schau dir mal hier das Pin Mapping des MEGAs an:
http://www.arduino.cc/en/Hacking/PinMapping2560
Pin 4 ist nicht mir PORTD bit 4 verbunden, du fragst den falschen IO ab.

BTW: Für C (ähnlichen) Code bitte die Formatierung verwenden:
1
[c]C-Code[/c]
Damit ist der Code um einiges angenehmen zu lesen.

: Bearbeitet durch User
von key-board (Gast)


Lesenswert?

müsste es nicht der PG5 sein?

Pinnummer 1(auf dem Prozessor), Pinname PG5, MappedPinName Digital pin 4 
(PWM)

jedenfalls danke. das War der entscheidende Tipp :)
mit
1
if((PING & B00100000))

funktioniert es. hab diese Liste vorher nie gefunden. nach sowas in der 
art gesucht hab ich schon... naja jedenfalls danke auch für den Tipp wie 
ich code hervorheben kann

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.