Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahlerfassung via CN37 mittels Interrupts
Hi,
Ich versuche einen CNY37(Gabellichtschranke) auszuwerten. Dieser soll zur Drehzahlerfassung bei einer Taktscheibe(20 Striche) dienen.
Wenn ich den Output des CNY37 über den AD Wandler meines ATMega32 abgreife und einen Schwellwert definiere kann ich ohne große Probleme die Striche zählen.
Nun möchte ich Ihn jedoch mit Hilfe eines Interrupts abfragen.
Dazu habe ich folgenden Programmcode entworfen:
$crystal = 16000000
$baud = 9600
Config Int0 = Falling
On Int0 Enc1
Enable Interrupts
Enable Int0
Dim Umdrehung As Single
Do
Loop
Enc1:
Umdrehung = Umdrehung + 1
Print Umdrehung
Return
Nun mein Problem:
Irgendwie zählt er manchmal garnicht hoch bzw wahnsinnig schnell.
Jedoch bei weitem nicht Richtig.
Ist der Code falsch, bzw habe ich da einen falschen Ansatz oder ist meine Schaltung zur Binearisierung falsch? ->
http://www.ftcommunity.de/bilder/sensoren/schaltplancny37.jpg
MfG
Rasmus
Hallo Rasmus,
warum eine Single Variable, kommen doch keine Zahlen mit nachkommestellen vor. Versuch mal wenn du nir hochzählen willst mal eine Word, und nimm mal den Print Befehl aus dem Interrupt. Kannst du in die Hauptschleife machen.
Gruss Frank
Mhh....!
Könnte vieleicht auch was helfen den internen Pullup widerstand zu aktivieren!
Sonst hat er keinen definierten Pegel und flackert wild umher!
Viel Spaß noch!
Timo
SprinterSB
04.08.2005, 08:57
Eine Gabellichtschranke kann ähnliche Effekte erzeugen wie ein prellender Taster. Das Zeug softwaremässig zu entprellen sollte helfen.
Ausserdem ist darauf zu achten, daß alle Zugriffe auf Objekte, die im Interrupt verändert werden, atomar geschehen.
Wenn zB 'Umdrehung' 16 Bit breit ist und du im Hauptprogramm auf diesen Wert zugreifst, kann nach dem Lesen/Schreiben des ersten Bytes ein Interrupt auftauchen und dir den Wert unsinnig machen.
@emulein
Sorry, die Single Variable hatte ich noch aus einer früheren Version.
Das mit dem printen in der Hauptschleife habe ich auch schon ausprobiert, bringt aber nichts.
@Omit Ich habe einen externen Pulldown(siehe Link), muss ich dann trotzdem den internen Pullup aktivieren, und wenn ja, wie?
@SprinterSB Was ist softwaremässiges entprellen und wie realisiere ich das in Bascom?
Das mit dem unerwarteten Interrupt ist ja schon zu hören ;-) , aber wie kann man das verhindern, bzw kann man das überhaupt verhindern, oder vorbeugen, weil sonst bringt einem Interrupts ja gar nicht, wenn sie auftauchen wann sie wollen.
MfG
Rasmus
SprinterSB
04.08.2005, 11:05
Ich kann dir hier Tipps geben, aber nicht zu BASIC.
Entprellen kannst du zB so. Jede Methode hat ihre Vor- und Nachteile:
- In einem Timer Interrupt zählst du eine Var hoch (auf Überlauf achten).
- Im INT0 prüfst du die Var. Ist sie kleiner als ein vorgegebener Wert, ändert sich nix an Umdrehung, ansonsten wird Umdrehung weiter gezählt.
- Danach setzt du die Var zurück auf 0.
- Im externen Interrupt (INT0) deaktivierst du INT0, ziehst einen Timer auf und aktiviert diesen und einen dazu gehörenden Interrupt.
- Im Timer Interrupt deaktivierst du den Timer wieder, setzt INT0-Flag zurück und aktivierst INT0.
Du benutzt nicht INT0, sondern schaust in regelmässigen Abständen in einem Timer-Interrupt nach, ob sich was getan hat oder ob INT0-Flag gesetzt ist. INT0 Flag wird auch dann gesetzt, wenn INT0 inaktiv ist. Falls du das Flag verwendest, wieder zurücksetzen.
hardwaremässig über ein RC-Glied
Um Codestücke vor Korruption zu schützen, kannst du kurzzeitig Interrupts global deaktivieren. Oder den betreffenden Interrupt, der Probleme machen könnte. Nach dem Reaktivieren der Ints wird dann die ISR ausgeführt weil die IRQ-Flags ja noch gesetzt sind.
Also das entprellen was Sprinter meinte ist genau das selbe was ich meine!
Du verhinderst das Prellen in dem du den Pin auf HIGH setzt...!
Z.B:
PORTD = &B0000001 Der PIN 0 von Port D ist jetzt auf HIGH aktiv gesetzt.
Damit verhinderst du das Prellen was der Sprinter meinte!
Mfg Timo
@SprinterSB
Ich habe die 1. und 3. Methode ausprobiert, wodurch ich nicht mehr, die von mir genannten schnellen Vergrößerung der "Umdrehung" Variable hatte. Dafür konnte ich bei gleichmässiger Geschwindigkeit die Impulse auf 80% Genauigkeit zählen(was bei weitem nicht genug ist). Wenn ich jedoch die Geschwindigkeit änderte hat er wieder gar nichts gezählt. Auch die Änderung der Intervalle des Timers brachte nichts.
@Omit
Wenn ich meinen Pin intern auf High ziehe bleibt er die ganze Zeit auf dem Highpegel. Ich habe ja extern auch schon einen Pulldown, sodass das daher wahrscheinlich nicht funktioniert.
Ich bin doch nicht der erste, der eine Drehzahlerfassung mit dem CNY37 oder ähnlichen realisiert, oder?
MfG
Rasmus
Javik hat mich auf die Idee der Verwendung eines Operationsverstärkers gebracht. Denn da würde ich ja einen klareren TTL Pegel haben. Hinter dem folgenden Link verbirgt sich so eine Schaltung(jedoch für den CNY70(Reflexkoppler)) -> http://www.robotmaker.de/linie.html
Meint ihr das wäre ein vernünftiger Ansatz?
MfG
Rasmus
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.