Warum nicht einfach einen Counter vom MCU hochzaehlen und per INT auslesen. Ich mache das alle 65ms und regel somit 2 Motoren. Das funktioniert recht gut. Der Nachteil man braucht 2 Counter. Intresse an dem Code?
Hallo zusammen,
Ich möchte mit euch gerne mal eine optimale Lösung zum Thema Drehzahlerfassung austüfteln.
Das problem ist ja, dass je nach Programmgröße die Drehzahl nicht wirklich an einem Normalen PIN eines MCs erfasst werden kann.
Meine Idee dazu wäre:
Man steuert mit dem Drehzahlimpuls einen COUNTER an ( Externes IC ).
zB 8Bit Binärzähler.
Im MC programmiert man einen Counter, der nach jeder Sekunde einen Interrupt ausführt, welcher dann dazu genutzt wird den Binärzähler auszulesen.
ABER um nicht 8 BITs des MCs zu benutzen könnte man auch folgendes machen.
Den Counter umkehren ( count down ) und so lange Impulse an den Counter schicken bis er Leer ist. nach dem nächsten interrupt wird der Counter wieder in normalmodus versetzt und er zählt wieder die drehzahlimpulse.
Dadurch sind 0-255 Drehungen pro sekunde möglich. oder pro halbe sekunde, jenacdem wie man es machen will....
Was haltet Ihr davon?
Nur kenne ich kein COUNTER-IC, welches bei 0 ein signal gibt, und auch noch ein UP/DOWN counter ist.
Aber zusammen erreicht man mehr, wisst ihr da was?
Was habt Ihr für Ideen?
Gruß,
Franz
Warum nicht einfach einen Counter vom MCU hochzaehlen und per INT auslesen. Ich mache das alle 65ms und regel somit 2 Motoren. Das funktioniert recht gut. Der Nachteil man braucht 2 Counter. Intresse an dem Code?
Hallo,
Danke für die Antwort.
Das st wohl die einfachste Lösung ....
Könntest mir den Code schicken? oder hier posten?
Danke!
Gruß,
Franz
Schön, wenn Du schon eine andere Lösung hast.Nur kenne ich kein COUNTER-IC, welches bei 0 ein signal gibt, und auch noch ein UP/DOWN counter ist.
Wenn der Zähler kein up/down Zähler ist, dann kann man den Zähler auch bis zum Überlauf hochzählen.
Speist man dabei die Zählimpulse zum Auswerten über eine EXOR Verknüpfung in das Zählsignal ein, dann gehen die während der Auswertung eintreffenden Zählimpulse auch nicht verloren. (Nur mit sehr geringer Wahrscheinlichkeit.)
Das gesuchte Signal ist dann der Überlauf oder auch das MSB.
Manfred
Ich müßte suchen, aber solche Preset-Counter gibt es fix und foxi, genau für diesen Zweck. (SN74160, 74161)
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Kannst Du noch ein bisschen dazu sagen welche Eigenschaften eines Zählers für diesen Zweck geeignt sind.solche Preset-Counter gibt es fix und foxi, genau für diesen Zweck
8bit, up/down, kombinierte clock Eingänge?
Manfred
Dazu könnte ich noch einen Ton abgeben,
Man könnte ja die 8 Ausgänge eines 8Bit Counters mit 8 Dioden auf einen Pin des MCs leiten, damit wüsste der MC immer wann der Counter 0 erreicht. Einen anderen PIN des Controllers müsste man mit Reset des Counters verbinden.
Ich bin aber trotz allem schon gespannt die Idee von "kater" zu testen.
Sein Code wäre noch der hit hier
Gruß,
Franz
Also mein Programm ist noch nicht ganz fertig. Ich hatte meine Drehzahl die ganze Zeit mit Digitalen Widerstaende gestellt, doch das ist zu bloede. Ich versucht heute mal PWM und passte mein Programm dann darauf an.
Das Grundgeruest kann ich aber schonmal freigeben _
Code:/* * Motordrehzahlreglung, geschrieben fuer einen ATMega8 mit 8MHz. * Das Programm ist fuer 2 Motoren geschrieben. Die Lichtschranken * werden ueber eine Gatter Logig an Pin 6 (T0) angeschlossen. Es wechselt * alle 62ms die Lichtschranke und vergleicht den Wert der in das Timer/Counter * Register0 geschrieben wuerde mit einem Sollwert. Danch werden die Motoren langsamer * oder schneller gestellt. * */ #include <stdlib.h> #include <avr/io.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <stdint.h> #define nop() asm volatile( "nop" ); #define MS PB0 #define NORMALSPEED 20 volatile uint16_t wayLeft = 0, wayRight = 0, wayLeftOld = 0, wayLeftDiff = 0, wayRightOld = 0, wayRightDiff = 0; volatile uint8_t impulseLeft = 0, impulseRight = 0, testLeftWheel = 1, speedLeft = 0, speedRight = 0, geradeausFahren = 1; // Timer1 SIGNAL(SIG_OVERFLOW1) { // Welches Rad ueberpruefen wir? if (testLeftWheel == 1) { wayLeftOld = wayLeft; // Die Lichtschranke sendet auch manchmal im Stillstand einen Wert von 1 if (TCNT0 <= 1) impulseLeft = 0; else impulseLeft = TCNT0; wayLeft += impulseLeft; wayLeftDiff = wayLeft - wayLeftOld; if (impulseLeft != speedLeft) { if (impulseLeft < speedLeft) { // Irgend etwas tun damit der linke Motor schneller dreht nop(); } else { // Irgend etwas tun damit der linke Motor langsamer dreht nop(); } } testLeftWheel = 0; // Rechter Motor auswaehlen PORTB |= (1 << MS); } else { wayRightOld = wayRight; if (TCNT0 <= 1) impulseRight = 0; else impulseRight = TCNT0; wayRight += impulseRight; wayRightDiff = wayRight - wayRightOld; if (impulseRight != speedRight) { if (impulseRight < speedRight) { // Irgendetwas tun damit der rechte Motor schneller dreht nop(); } else { // Irgendetwas tun damit der rechte Motor langsamer dreht nop(); } } testLeftWheel = 1; // Linker Motor auswaehlen PORTB &=~ (1 << MS); } if (geradeausFahren == 1) { if (wayLeftDiff < wayRightDiff) { // Der rechte Motor hat eine groessere Strecke zurueckgelegt als der linke. // Den rechten Motor langsamer fahren lassen } else if (wayLeftDiff > wayRightDiff) { // Der linke Motor hat eine groessere Strecke zurueckgelegt als der recht. // Den linken Motor langsamer fahren lassen. } } // Timer auf 0 setzten TCNT0 = 0; } int main(void) { DDRB = 0xFF; // PORTB as Output DDRD = 0x00; // PORTD as Input PORTD = 0xff; // interne Pull-Ups an allen PortD-Pins aktivieren TCCR0 |= (6<<CS00); // Ext. Clock, falling edge TCCR1B |= (2<<CS10); // Clk/8 TIMSK |= (1 <<TOIE1); // Timer-1 Interrupt einschalten speedLeft = 30; speedRight = 30; // Interrupts aktivieren sei(); // Hauptschleife while (1) { // Irgenwelche Befehler ueber z.B USART empfangen } }
Ich hab jetzt nachgesehen, 74160 ist BCD, 74161 wäre ein binärer Zähler. (4-Bit, beide sind aber kaskadierbar)
Muß allerdings revidieren: Diese beiden IC können nur "up" counten.
SN74192, 74193 (BCD, bin) wären die richtigen Burschen.
(Ich hoff', das Zeugs ist verfügbar)
Wie gesagt, man kann/muß zwei oder mehrere kaskadieren, jeder hat 4-Bit. Die Zählerstände sind parallel verfügbar
Man kann also wie bei der Maus arbeiten: Aus dem Encoder läßt man up/down zählen, und liest in bestimmten Intervallen aus (+clear)
oder man lädt eine Zahl und nimmt das Ripplecarry als interrupt beim Nulldurchgang (Das würde einem Zahlengleichstand entsprechen),
Up/down erfolgt durch zwei verschiedene Clock-Pins, das müßte man man Encode-design berücksichtigen.
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
...oder man nimmt nen Tiny wie 2313 und programmiert den als Zähler, da braucht man nicht kaskadieren und lange runzusuchen
Und dürfte fast billiger sein als die selteten TTL-Chips und platzsparender als 2 kaskadierte Counter allemal.
Disclaimer: none. Sue me.
Lesezeichen