so...hab mir einen Zähler so vorgestellt !
void Counter_REAR()
{
detachInterrupt(5);
T_rear=pulseIn(5, HIGH)+pulseIn(rear_axle, LOW,10000);
attachInterrupt(5,Counter_REAR,FALLING);
}
vorher in der void Setup()
attachInterrupt(3,Counter_REAR,FALLING);
ob falling oder rising ist in dem Fall eher sekundär, würde ich sagen!
bin ich da schon am richtigen Weg ?!
bei Pulslänge mit mehr als 10ms wird inf0 ausgegeben...
Karl Heinz schrieb:> Waren wir uns nicht schon mal (in einem anderen Thread) darüber einig,> dass pulsIn gelinde gesagt 'scheisse' ist?
jup...sind uns nun einig!
trotzdem bitte noch mal:
void Counter_L_F()
{
detachInterrupt(3);
int counter_pulse_l_f=0;
boolean pulse_l_f;
if (pulse_l_f==HIGH)
{
counter_pulse_l_f++;
}
if (counter_pulse_l_f==150)
{
counter_pulse_l_f=0;
T_l_f=micros();
}
attachInterrupt(3,Counter_L_F,RISING);
}
dachte mir inzwischen, dass ich das vl so löse, dass ich nen Counter
hochzählen lasse und dann mittels micros() die Zeit ausgeben lasse, die
bis dahin vergangen ist !
jetzt fehlt mir nur noch ein Ansatz, wie ich mittels Interrupt diese
Messung auslöse, das erst bei ner gewissen Frequenz...aber so
funktioniert das nicht ...der Compiler gibt aber keinen Fehler
aus....der ZEITFAKTOR fehlt mir noch da drin!
das allein reicht nicht...wenn es überhaupt funktioniert
--->
attachInterrupt(3,Counter_L_F,150*RISING);
Peter Dannegger schrieb:> IDE?> Target?> Includes!> Kommentare!
Als Arduino-Programmierer sieht man sofort, wofür das ist:
IDE - Arduino-Software
Target - ein Arduino-Board
Includes - automatisch eingebundene Arduino Core-Libraries
Kommentare - bei dem Scheiß, den er da als Code zusammenschreibt, ist
eigentlich jeder Kommentar überflüssig.
Vielleicht sollte er erstmal grob skizzieren, was er machen möchte.
Sein Ziel ist ja wahrscheinlich nicht nur "schreibe ein möglichst
irrsinniges Programm, das fehlerfrei kompiliert werden kann", sondern er
möchte wohl irgendwas mehr oder weniger sinnvoll ablaufendes
programmieren.
Bei Ansicht des Tohuwabohu-Arduino-Codes fällt mir nur beim besten
Willen nicht ein, was das sinnvolles sein könnte.
Aber vielleicht kann er das ja nochmal genauer erklären.
Jürgen S. schrieb:> Kommentare - bei dem Scheiß, den er da als Code zusammenschreibt, ist> eigentlich jeder Kommentar überflüssig.
Kommentare sind für einen selber da, um auch später noch zu verstehen,
was man mal hingeschrieben hat.
Sie können aber auch sofort aufzeigen, daß man sich vorher keine
Gedanken über die Funktion gemacht hat. Sie sind sozusagen eine erste
Gütekontrolle.
Wer meint, ganz ohne Konzept einfach so drauflos schreiben zu können,
wird nicht weit kommen.
Peter Dannegger schrieb:> Kommentare sind für einen selber da, um auch später noch zu verstehen,> was man mal hingeschrieben hat.
OK, ich weiß nicht, was sich der TO dabei gedacht hat, als er seinen
Code schrieb. Aber ich kommentiere seinen Code mal wie folgt:
1
// Wie ich Arduino-Code schreibe, der NICHTS macht
2
voidCounter_L_F()// ich mache mal eine Interrupt-Behandlungsroutine
3
{
4
detachInterrupt(3);// Interrupt-Behandlung? Weg damit!
5
intcounter_pulse_l_f=0;// Setze counter_pulse_l_f auf null
6
booleanpulse_l_f;// Deklariere pulse_l_f mit einem unbestimmten Zufallswert
7
if(pulse_l_f==HIGH)// Wenn dieser unbestimmte Zufallswert HIGH ist
8
{
9
counter_pulse_l_f++;// erhöhe counter_pulse_l_f um 1
10
}
11
// Jetzt ist also counter_pulse_l_f entweder 0 oder 1
12
if(counter_pulse_l_f==150)// Prüfe, ob counter_pulse_l_f auf magische Weise 150 geworden ist?
13
{
14
counter_pulse_l_f=0;// in dem Fall setze den auf magische Weise erhöhten Wert wieder auf 0
15
T_l_f=micros();// und lies den Stand des Mikrosekunden-Timers aus
16
}
17
attachInterrupt(3,Counter_L_F,RISING);// Interrupt-Behandlung? Warum habe ich die oben weggehauen? Her damit!
18
// Aufgabe erfolgreich gelöst: Der Code verbraucht Rechenzeit und macht: NICHTS!
19
}
Mit Kommentaren dran wird's irgendwie auch nicht besser als es ohne
schon ist.
Wobei ich natürlich nicht weiß, was der TO als Kommentar zu seinem Code
geschrieben hätte.
> boolean pulse_l_f; // Deklariere pulse_l_f mit einem unbestimmten
Zufallswert
> if (pulse_l_f==HIGH) // Wenn dieser unbestimmte Zufallswert HIGH ist
Och neee. Im Ernst jetzt?
...es ist schade, dass man eigentlich sogar teilweise FRECHE Kommentare
hier erhält!
zu meiner Verteidigung, wenn ich schon auf einer Anklagebank sitzen
soll, ich hab vorher NIE mit Mikrocontrollern gearbeitet und teilweise
ist die Schreiblogik nicht so ganz zu verstehen für mich...ist so....und
da kann ich versuchen, was ich will!
FAKT IST: ich muss 3 Drehzahlen messen ohne die Loop zu belasten (ohne
wird nicht gehen, das ist klar)
also, ich bin da auf mich allein gestellt und erhoffte hier ein paar
Vorschläge, keinen SENF (...dank denjenigen, die kommentieren, dass mein
Code Senf ist)
ich hab leider nur mehr 3 Timer (16bit) zur Verfügung und benötige 4?!?!
ISR(TIMER3_OVF_vect) //für das linke vordere Rad
{
Measure_l_f_result++;
if (Measure_l_f_result==50)
{
Measure_l_f=TCNT3; //übergeben vom Counter an
Measure_l_f
TCNT3=0; //Rücksetzen des Counters und
der Variable....entspricht etwa CTC-Einstellung
Measure_l_f_result=0;
}
}
vorher definier ich den Timer/Counter so ->
TCNT3=0; //Drehzahl-Counter L_F
Startwert
TCCR3A=0; //zuerst Register A und B
auf Standard-Werte setzen
TCCR3B=0;
TIMSK3|=(1<<TOIE3); //wie arbeitet Interrupt->
Timer Overflow
TCCR3B|=(1<<CS32)|(1<<CS31)|(1<<CS30); //steigende Flanke wird
gezählt
bin ich da immer noch auf dem Holzweg?
Bitte, wenn geht, einfach nur dann kommentieren, wenn es ohne "sinnloses
Auskotzen" der Meinung geht
Rene Trattner schrieb:> ...es ist schade, dass man eigentlich sogar teilweise FRECHE Kommentare> hier erhält!
Tja, falls Du es nicht wusstest: Ein Forum ist kein Wunschkonzert!
Und wenn Du Dir die Frechheit herausnimmst, völlig unkommentierten
Quellcode zu posten, der absolut nichts macht, außer mit 0 und 1 zu
hantieren und auf 150 zu prüfen und damit Rechenzeit sinnlos zu
verbraten, dann kann es Dir tatsächlich passieren, dass Dir jemand mal
passende Kommentare dazu schreibt.
Noch dazu, wo Du nicht mal wenigstens grob beschreibst, was der Code
eigentlich machen soll.
> FAKT IST: ich muss 3 Drehzahlen messen ohne die Loop zu belasten (ohne> wird nicht gehen, das ist klar)
OK, also "Drehzahlmessung". Drehzahl ist "Umdrehungen pro Zeit", d.h. Du
mußt jeweils die Umdrehungen und die Zeit erfassen. Die Umdrehungen
erfasst Du offenbar an einem Input-Pin, an dem periodisch HIGH und LOW
"Impulse" geliefert werden. Das kann man mit einer Interrupt-Routine
erfassen.
Also setzt Du z.B. in der setup-Funktion einen Interrupt auf, der
entweder auf steigende (RISING) oder fallende (FALLING) Flanke einen
Interrupt erzeugt. Zum Beispiel auf steigende Flanke wie von Dir oben
vorgeschlagen:
1
voidsetup()
2
{
3
// ...
4
attachInterrupt(3,Counter_L_F,RISING);
5
// ...
6
}
Zur Interrupt-Behandlung brauchst Du eine Interrupt-Behandlungsroutine.
Variablen, die sowohl innerhalb der Interruptroutine als auch im
sonstigen Programm gelesen und/oder gesetzt werden sollen, müssen
zwingend mit den Zusatz "volatile" deklariert sein. Um Impulse zu zählen
und die Zeit zu berücksichtigen, brauchst Du zwei Variablen: Die eine
zählt die Anzahl der Impulse hoch, die andere merkt sich die Zeit. Für
eine hohe zeitliche Auflösung am besten den Stand des micros() Timers.
So dass Deine Variablendeklaration und Interrupt-Behandlungsroutine so
aussehen:
1
volatileunsignedintcounter_ISR;
2
volatileunsignedlongtimer_ISR;
3
4
voidCounter_L_F()
5
{
6
counter_ISR++;// Impulse zählen
7
timer_ISR=micros();// Zeit merken
8
}
Fertig ist der Code für die Interruptbehandlung: Umdrehungen und Zeit.
Immer nachdem die Interruptbehandlung gelaufen ist, ist die Zählvariable
um 1 höher als vorher und in der Variablen "timer_ISR" ist der Zeitpunkt
vermerkt, wann diese letzte Impulszählung erfolgt ist.
Wobei dies Code für relativ langsame Drehzahlen bis einige hundert
Umdrehungen pro Minute ist. In Sonderfällen wie "extrem hohe Drehzahlen"
zusammen mit "Drehzahlauswertung nur alle paar tausend Impulse" kann die
Zeiterfassung auch weggelassen werden, weil es dann bei der späteren
Drehzahlberechnung kaum einen Unterschied macht, ob die Drehzahl nun aus
4711 oder 4712 Impulsen berechnet wird.
Soweit klar?
Jetzt fehlt dann nur noch der passende Code in der loop-Funktion und
fertig ist die Drehzahlmessung.
P.S.: Du müßtest dringend die BASICS der Programmierung lernen. So wie
Du Dich oben damit blamiert hast, eine Variable auf 0 oder 1 zu setzen,
um diese danach mit einer if-Bedingungen auf 150 zu prüfen, fehlen Dir
absolut die Grundkenntnisse, um irgendwas sinnvoll zu programmieren. Und
Interruptprogrammierung ist eher schon ein Thema für Fortgeschrittene.
VIELEN DANK!!!
das war sehr verständlich!
ich glaub, damit krieg ich es hin!!
und blamieren ....ich will es ja kapieren.....blamieren würde ich mich,
wenn ich behaupten würde, dass ich es kapier...das habe ich aber nie!!!
danke rechtschön erstmal!!
Rene Trattner schrieb:> das war sehr verständlich!>> ich glaub, damit krieg ich es hin!!
Ich lese zwar die Worte, aber glauben kann ich das nicht.
Denn eine völlig saubere Auswertung der Drehzahl in der loop ist etwas
komplizierter/aufwändiger als das bisschen, was die
Interruptbehandlungsroutine macht und erfordert ein absolut sauberes
Zusammenspiel mit den "volatile" Variablen.
Und zwar sowohl, wenn die Auswertung "pro Umdrehung" bzw. "möglichst
schnell" oder auch "in gleichen Zeitabständen von z.B. 1x pro Sekunde"
stattfinden soll.
Also im Zweifelsfall nochmal drübergucken lassen oder nachfragen, bevor
Du Dir irgendwas zusammenbastelst, das dann nur "fast immer"
funktioniert und Dir manchmal gewaltige "Ausreißer" als Drehzahlwerte
zurückliefert.
Rene Trattner schrieb:> ich muss 3 Drehzahlen messen ohne die Loop zu belasten
Im einfachsten Fall nimmt man dazu 3 externe Interrupts und einen
freilaufenden Timer.
Man muß allerdings zuerst mal die Meßgrößen festlegen (min, max,
Auflösung, Meßdauer).
Dann setzt man den Timer so, daß er bei min noch nicht überläuft.
Reicht dann die Auflösung nicht, kann man den Timer auf 24 oder 32 Bit
erweitern.
Beitrag "AVR Timer mit 32 Bit"
Und sage endlich mal, um welches Target es geht.