Forum: Mikrocontroller und Digitale Elektronik Attiny2313 als Drezahlmesser benutzen


von Wilfried B. (hilflosueberfordert)


Lesenswert?

Guten Morgen,

ich sitze jetzt schon seit fast 13 Stunden vor folgendem Problem:

Ich möchte mit einem Attiny 2313 und einer IR-Lichtschranke dei Drehzahl 
messen. Zuvor soll der Attiny mittels PWM den Motor ansteuern.

Ich bekomme es nicht in meinem Kopf rein wie ich die Impulse der 
Lichtschranke innerhalb einer Sekunde zählen kann. Ich habe jetzt zig 
Stunden mit Google und den Kapiteln zu dem Timer0 im Datenblatt gelesen. 
Ohne Erfolg, im Inet finde ich zwar einige Seiten die das Thema 
behandeln, doch entweder helfen diese mir nicht weil es nicht in Bascom 
ist oder das Thema kommt nicht zu einem für mich anwendbarem Ergebnis. 
Schließlich will ich nicht die Zeit zwischen 2 Impulsen messen (da ich 
nicht begreife wie ich es dann auf eine Minute hochrechnen soll).

Wie zu sehen ist ist mein bisheriges Programm Schrott, sollte auch nur 
"mal eben" als Grundgerüst geschrieben werden. Bis ich eben auf das 
Problem mit dem zählen der Impulse binnen einer Sekunde gekommen bin.

Ich hoffe irgendwer von euch kann mir weiter helfen.


$regfile = "2313def.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

'Drehzahlmessung mittels PWM und IR-Schranke


Config Pinb.2 = Input                             'zählen der IR-Signale
Config Portb.3 = Output                           'PWM zum Motor
Config Pind.6 = Input                             'Taster zum Modi 
wählen
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Up , Compare B 
Pwm = Disconnect , Prescale = 1
Config Timer0 = Counter , Edge = Rising , Compare A = Clear , Compare B 
= Disconnect

Moditaster Alias Pind.6
Ir_schranke Alias Pinb.2

Config Debounce = 500
Debounce Pind.6 , 1 , Pr
Debounce Pind.5 , 1 , Pr

Dim Rps As Word
Dim Rpm As Word
Dim Modus As Byte

Hauptprogramm:

Do

If Moditaster = 1 Then Gosub Sollumdrehung
If Ir_schranke = 1 Then Gosub Istumdrehung




Loop

End

Sollumdrehung:

Modus = Modus + 1                    'Zähler für Frequenz ein hochzählen

If Modus = 1 Then Pwm1a = 972
If Modus = 2 Then Pwm1a = 921
If Modus = 3 Then Pwm1a = 870
If Modus = 4 Then Pwm1a = 819
If Modus = 5 Then Pwm1a = 786
If Modus = 6 Then Pwm1a = 716
If Modus = 7 Then Pwm1a = 665
If Modus = 8 Then Pwm1a = 614
If Modus = 9 Then Pwm1a = 563
If Modus = 10 Then Pwm1a = 512
If Modus = 11 Then Pwm1a = 460
If Modus = 12 Then Pwm1a = 409
If Modus = 13 Then Pwm1a = 358
If Modus = 14 Then Pwm1a = 307
If Modus = 15 Then Pwm1a = 256
If Modus = 16 Then Pwm1a = 204
If Modus = 17 Then Pwm1a = 153
If Modus = 18 Then Pwm1a = 102
If Modus = 19 Then Pwm1a = 51
If Modus = 20 Then Pwm1a = 0

If Modus > 20 Then Modus = 0            'Zähler für Frequenz zurück 
setzen

Return


Istumdrehung:

Rps = Rps + 1                                        'Zähler für 
Drehzahl
Rpm = Rps * 30
Lcd Rpm

Return

von Bernard B. (bernard_b)


Lesenswert?

I'm sorry for writing in English, but I still hope it might be of any 
help.
I think it's easier to use interrupts for counting. At your ATTiny2313 
there are 2 interrupts, which are :

- INT0 (Pin D2)
- INT1 (Pin D3)
I used INT0 in my sourcecode. This interupt-pin will start a part of 
(source)code, when a signal raises from Gnd (0 Volt) to Vcc (3.3 or 5 
Volts).

Next, the microcontroller contains 2 timers. Best is to use a timer, 
which will not completely gets a full countdown, within 1 second. By 
this, you get a pretty accurate timer at use. Like, you, I choose for 
this sourcecode also Timer1, which is a 16-bit timer (65535).

The only problem you might face, is that I used Int0 (pin D2) for 
detecting the signal, while you use Pin B2....
When using an INT0, you can't use this pin for other purposes, like 
steering devices at this pin (D2).

NOTE : When using the interrupts and Timer, there's almost no effect in 
execution of the "Main Program" (read : delay).

I've included comments, hoping this will help you to figure out how this 
sourcecode operates :

====[ Start sourcecode ]====
$regfile = "2313def.dat" 'We deal with a AT90S2313 or alike
$crystal = 4000000       'Clockspeed of this microcontroller
$hwstack = 40            'Dunno, what it means
$swstack = 16            'but I agree, this works
$framesize = 32          'most of the time perfect for me too...

Dim Rpm as Integer        'Variable, updated Rpm-value
                          '(use for calculations in MAIN PROGRAM)
Dim Dummy_Rpm as Integer  'Variable for tracking / counting Rpm

   On Timer1 1_second_interval
  '1 Overflow / seconde needed
   Config Timer1 = Timer , Prescale = 64
  '4.000.000 / 64 = 62500 increments / sec
  '1 second takes 62500 increments  => 65536 - 62500 = 3036
   Enable Timer1

  'INTERRUPT FOR COUNTING High-signals
   Config Int0 = Rising    'When signal goes from GND to 5V
   On Int0 Int0_Rpm        'When Interrupt occurs,
                           'go routine, called Int0_Rpm
   Enable Interrupts       'Activate Interrupts
   Enable Int0             'Let Int0 do its counting

'MAIN PROGRAM
 Do
  'In this main loop, you can work with the always updated Rpm
  'Like the steering of the motor
 Loop


'Routines for INTERRUPTS
Int0_Rpm:
  incr Dummy_Rpm          'Equal to : Dummy_Rpm = Dummy_Rpm + 1
Return

1_second_interval:
  TIMER1 = 3036           'Let Timer go for another second
  Rpm = Dummy_Rpm         'The value to send to LCD or use for 
calculations
  Dummy_Rpm = 0
Return
====[ End sourcecode ]====

Finally, I don't know what your "Solleumdrehung"-part does, but I'm 
pretty sure you can rewrite it back into a mathematical function. Maybe 
you can use MS Excel, to figure out the requested function for these 
values.

Just my 2 cents.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Wilfried Bergmann schrieb:

> ich sitze jetzt schon seit fast 13 Stunden vor folgendem Problem:
>
> Ich möchte mit einem Attiny 2313 und einer IR-Lichtschranke dei Drehzahl
> messen.

Da würde ich dir dringend empfehlen, dir ein anderes Hobby zu suchen. 
Dieses überfordert deine intellektuellen Fähigkeiten offensichtlich 
massiv.

> Ich bekomme es nicht in meinem Kopf rein wie ich die Impulse der
> Lichtschranke innerhalb einer Sekunde zählen kann.

Du kannst nicht zählen? Oder keine Sekunde abmessen?

> Ich habe jetzt zig
> Stunden mit Google und den Kapiteln zu dem Timer0 im Datenblatt gelesen.
> Ohne Erfolg, im Inet finde ich zwar einige Seiten die das Thema
> behandeln, doch entweder helfen diese mir nicht weil es nicht in Bascom
> ist

Die verwendete Sprache ist völlig Wurscht, wenn es darum geht, ein 
allgemeines Prinzip und die Nutzung der vorhandenen Hardware dafür zu 
begreifen.
Die Sprache spielt nur dann eine Rolle, wenn man garnicht selber 
programmieren will, sondern nur die passende Vorlage für eine 
Copy&Paste-Operation sucht.

> Schließlich will ich nicht die Zeit zwischen 2 Impulsen messen (da ich
> nicht begreife wie ich es dann auf eine Minute hochrechnen soll).

OMG. F=1/P. Oder, für rpm: F=60/P

Also eine simple Division, wie so schon Viertklässler beherrschen 
(zumindest beherrschen sollten).

P ist die Periodendauer, also der Abstand der Signale. Die braucht man 
in Sekunden, hat sie aber in der Regel in Taktzyklen (oder irgendwelchen 
Vielfachen davon).

Wie kommt man nun von den Taktzyklen zur Periode? Ganz einfach. Man 
multipliziert die Zahl der Taktyklen mit der Dauer eines Taktyklus.

P=N*Pt

Eine einfache Multiplikation. Sollte ebenfalls ab der vierten Klasse 
sicher beherrscht werden.

Und wie kommt man auf die Dauer eines Taktyklus? Indem man die 
allgemeine Formel nach P umstellt und für die Frequenz die Taktfrequenz 
des Controllers einsetzt.

Pt=1/Ft

Auch wieder nur eine simple Division.

Nun kann man das Ganze auch zu einer einzigen Formel zusammenfassen, 
indem man die Formeln rückwärts ineinander einsetzt. Das führt erst zu

P=N/Ft

und dann zu

F=60*Ft/N

Sowas müßte so ungefähr ab der 5 oder 6 Klasse sicher beherrscht werden.

Wie gesagt, wenn du sowas Simples nicht aus dem Handgelenk ohne großes 
Nachdenken hinschreiben kannst, hast du das falsche Hobby!

von Chris (Gast)


Lesenswert?

Pin deiner Wahl aussuchen den Timer0 initialisieren nach der 
Initialisierung den Tiger starten und den Pin immer wieder abfragen bis 
die 1s um ist den Timer stoppen und das impulsregister auslesen.

1. Init Timer x
2. Timer x starten
3. Pinabfrage als loop / oder mit externen Interrupts
4. 1s um Timer stoppen und zählvariable auslesen

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

Die Pin-Abfrage kann man sich auch sparen. Die AVRs haben einen 
Timer-Modus, mit dem man direkt externe Ereignisse zählen kann.

Mit freundlichen Grüßen
Thorsten Ostermann

von Dieselwolf (Gast)


Lesenswert?

@C-Hater

Wenn Du schon am Morgen um 7 so eine Dreckslaune hast -wie sieht die
dann am Nachmittag gegen 16 Uhr aus?

Du bist offenbar nicht in der Lage, einen Sachverhalt vernünftig zu
erklären. Dann laß es gleich ganz. Es steht Dir nicht zu, Dir
unbekannte Leute zu beleidigen, daß die Fetzen fliegen.

Mache Dir klar, daß es Menschen gibt, die sich nicht jeden Tag mit
solchen Problemen befassen. Die brauchen eine "Zündfunken" -kein
Bashing!

SCNR
Dieselwolf

von m.n. (Gast)


Lesenswert?

Drehzahlen mißt man am besten mit reziprokem Messverfahren.
Suche nach "reziproke Drehzahlmessung" und versuche Sinn und Zweck zu 
verstehen.

von Jan R. (Gast)


Lesenswert?

Kurz erklärt.

-Interrupt an einer Flanke auslösen.
-bei der ersten Umdrehung Timerregister 0 Setzen und nicht auslesen.
-Bei der nächsten gleichen Flanke Timerregister auslösen und wieder 0 
setzen.
-Da du weißt, wie schnell der Systematik ist und welchen Vorteile du 
verwendest, kannst du den imerwert in Sekunden und dann in 1/s (Hz) 
umrechnen.
-Da die ISR Routine viel viel kürzer ist als die Zeit zwischen zwei 
flanken, ist der Entstehende Fehler vernachlässigbar.

von Dieselwolf (Gast)


Lesenswert?

Jan erklärte:
>-Da du weißt, wie schnell der Systematik ist und welchen Vorteile du
>verwendest, kannst du den imerwert in Sekunden und dann in 1/s (Hz)
>umrechnen.

Rasend schnell erklärt....

Noch mal langsam und mit weniger Sinnentstellung:
-Da Du weißt, wie schnell der Systemtakt ist und welchen Vorteiler 
Du
verwendest, kannst Du den Timerwert in Sekunden und dann in 1/s (Hz)
umrechnen.

von m.n. (Gast)


Lesenswert?

Jan R. schrieb:
> -Interrupt an einer Flanke auslösen.

Beim ATtiny2313 ist das der ICP-Eingang, der den aktuellen Wert von T1 
auf eine Taktperiode genau erfaßt.

> -Da die ISR Routine viel viel kürzer ist als die Zeit zwischen zwei
> flanken, ist der Entstehende Fehler vernachlässigbar.

Die Capture-Funktion arbeitet völlig unabhängig von einer ISR; dieser 
Fehler ensteht daher erst garnicht!

Um eine weitere 13 stündige Suche im I-net abzukürzen: 
Beitrag "einfache Drehzahlmessung mit ATmega88", wobei die Erfassung 
beim ATtiny2313 genauso abläuft.

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.