Forum: Mikrocontroller und Digitale Elektronik Gehversuch Zähler


von Rene T. (hifi-freak)


Lesenswert?

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...

von Schlumpf (Gast)


Lesenswert?

Zieh dir schonmal nen Helm auf.. denn gleich geht´s los! ;-)

von Karl H. (kbuchegg)


Lesenswert?

Waren wir uns nicht schon mal (in einem anderen Thread) darüber einig, 
dass pulsIn gelinde gesagt 'scheisse' ist?

von Rene T. (hifi-freak)


Lesenswert?

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);

von Peter D. (peda)


Lesenswert?

1
test.c: In function 'Counter_L_F':
2
test.c:3: warning: implicit declaration of function 'detachInterrupt'
3
test.c:5: error: 'boolean' undeclared (first use in this function)
4
test.c:5: error: (Each undeclared identifier is reported only once
5
test.c:5: error: for each function it appears in.)
6
test.c:5: error: expected ';' before 'pulse_l_f'
7
test.c:6: error: 'pulse_l_f' undeclared (first use in this function)
8
test.c:6: error: 'HIGH' undeclared (first use in this function)
9
test.c:13: error: 'T_l_f' undeclared (first use in this function)
10
test.c:13: warning: implicit declaration of function 'micros'
11
test.c:15: warning: implicit declaration of function 'attachInterrupt'
12
test.c:15: error: 'RISING' undeclared (first use in this function)

IDE?
Target?
Includes!
Kommentare!

: Bearbeitet durch User
von Jürgen S. (jurs)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Jürgen S. (jurs)


Lesenswert?

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
void Counter_L_F()  // ich mache mal eine Interrupt-Behandlungsroutine
3
{
4
  detachInterrupt(3);  // Interrupt-Behandlung? Weg damit!
5
  int counter_pulse_l_f=0; // Setze counter_pulse_l_f auf null
6
  boolean pulse_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.

von Vanille (Gast)


Lesenswert?

>  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?

von Rene T. (hifi-freak)


Lesenswert?

...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

: Bearbeitet durch User
von Jürgen S. (jurs)


Lesenswert?

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
  void setup()
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
volatile unsigned int counter_ISR;
2
volatile unsigned long timer_ISR;
3
4
void Counter_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.

von Rene T. (hifi-freak)


Lesenswert?

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!!

von Jürgen S. (jurs)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

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.