Forum: Mikrocontroller und Digitale Elektronik externes Interrupt wird beliebig ausgelöst (Motorrad)


von David (Gast)


Lesenswert?

Hallo,

ich bin dabei mir einen kleinen Tacho für mein Motorrad zu bauen.
Folgender Aufbau (bis jetzt):
µC Attiny 24
Reedkontakt gegen Masse, der an den INT0 Pin des µC's geht. Zusätzlich 
ein 10k gegen Vcc und ein 100nF von Pin gegen GND, interne Pullups an. 
Widerstand und Kondensator dienen zum entprellen.
Der Reedkontakt löst also das INT0 aus und ich messe von 2 Flanken die 
Zeit. Dabei wird bei einer fallenden Flanke eine LED eingeschaltet und 
bei einer steigenden die LED wieder ausgeschaltet.
Das ganze funktioniert auch wunderbar, auch die Entprellung.
Nur, wenn der Motor des Motorrades läuft, bekomme ich (vermutlich) 
dauernd irgendwelche Interrupts, da die LED blinkt, manchmal leuchtet 
und nicht ausgeht, etc. Es ist willkürlich.
Drehe ich das Rad bei ausgeschaltetem Motor, bekomme ich keine 
unbeabsichtigten Interrupts, sondern nur, wenn der Magnet tatsächlich am 
Magnet vorbeiwandert, leuchtet auch die LED kurz auf.
Hat jemand eine Idee, woran das liegen könnte bzw. was man dagegen 
machen kann?
Bevor ich keine sauberen Signale bekomme, brauche ich nicht weiter zu 
machen. Ach ja, es soll eine Lösung mit Reedkontakt sein, nicht mit 
Hallsensor oder ähnlichem. Das Entprellen funktioniert ja und macht auch 
keine Probleme.
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>
5
6
#ifndef F_CPU
7
#define F_CPU           8000000UL                   // processor clock frequency 8Mhz
8
#endif
9
10
#define LED      PA6    // Pin für Steuerung der LED des Modus
11
12
#ifndef TRUE
13
#define TRUE 1
14
#define FALSE 0
15
#endif
16
17
18
void init(void);             // Initialisiert die Ports, Enable global Interrupt
19
20
// Variablen in der ISR externes Interrupt 0
21
volatile uint16_t usStartTimeINT0 = 0;        // TCNT1-Wert bei der 1.Low-Flanke speichern
22
volatile uint16_t usEndTimeINT0 = 0;        // TCNT1-Wert bei der 2.Low-Flanke speichern
23
volatile uint8_t uchErsteFlankeINT0 = TRUE;      // Zu Beginn soll die erste Flanke eingelesen werden
24
volatile uint32_t ulGesamtzeitINT0 = 65535;      // Gesamtzeit in Timerzyklen des INT0 (Taktzeit inkl. Prescaler)
25
26
// Variablen in der ISR Timer1 Overflow Interrupt      
27
volatile uint8_t uchNrOverflowsINT0_TC1;          // Overflow Zähler
28
29
//Externes Interrupt INT0 Service Routine
30
ISR (INT0_vect){
31
  if (!(MCUCR & (1 << ISC00))){        // Interrupt bei fallender Flanke ist gestzt, wenn dieses Bit (für steigende Flanke) nicht gesetzt ist        
32
    if ( uchErsteFlankeINT0 ){        // Allererste Flanke?
33
      usStartTimeINT0 = TCNT1;      // Liest den aktuellen Start Wert des 16-bit Timers ein bei der 1. fallenden Flanke
34
      uchNrOverflowsINT0_TC1 = 0;      // Setzt die Overflows des INT0 des Timer1 (16-bit) zurück
35
      PORTA &= ~(1 << LED);        // LED ein
36
      uchErsteFlankeINT0 = FALSE;      // Erste Flanke = FALSE, die nächste Flanke ist nämlich die zweite Flanke        
37
    }
38
    else{                  
39
      usEndTimeINT0 = TCNT1;        // es wurde bereits die allererste Flanke eingelesen, dies sind folglich die nächsten
40
      PORTA &= ~(1 << LED);        // LED ein
41
      if ( (TIFR1 & (1 << TOV1)) && (!(usEndTimeINT0 & 0x8000)) ){  // liegt ein Timer1 (16-bit) Überlauf an, während die Routine abgearbeitet wurde
42
        uchNrOverflowsINT0_TC1++;    // Overflows des INT0 des Timer1 (16-bit) erhöhen, da mitgezählt werden muss
43
        TIFR1 = (1 << TOV1);      // TC1 OVF Flag löschen, da manuell abgehandelt
44
      }
45
      ulGesamtzeitINT0 = (uchNrOverflowsINT0_TC1 * 65536) + usEndTimeINT0 - usStartTimeINT0; // berechnet die Zeitdauer zwischen 2 Flanken
46
      usStartTimeINT0 = usEndTimeINT0;  // die alte Endzeit ist nun Beginn der nächsten Messung und damit die neue Startzeit
47
      uchNrOverflowsINT0_TC1 = 0;      // neue Messung --> OVF zurücksetzen
48
    }              
49
  }                    
50
  else{                  // sonst Interrupt bei steigender Flanke
51
    PORTA |= (1 << LED);        // LED aus
52
  }
53
  MCUCR ^= (1 << ISC00);        // Flankenerkennung toggeln                            
54
}                                
55
56
57
//Timer1 16-bit Overflow Interrupt Service Routine
58
59
ISR (TIM1_OVF_vect){
60
  uchNrOverflowsINT0_TC1++;            // Overflows zählen
61
}
62
63
int main(void)
64
{
65
  init();    // Ports intialisieren                
66
67
  while (1){
68
  
69
  } 
70
}
71
72
73
/*Funktion zum Initialisierein des µC*/
74
75
void init(void) {
76
77
78
  DDRA = 0x00;              // Datenrichtungsregister zunächst alle Eingang 
79
  DDRA |= (1 << DDA6);   // PA6 als Ausgang schalten für LED
80
  PORTA |= (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5) | (1 << PA6) | (1 << PA7); // LED aus+Pullups
81
  
82
  DDRB = 0x00;              // Datenrichtungsregister alle Eingang
83
  PORTB |= (1 << PB2);          // Pullup für INT0 anschalten
84
85
  sei();                  // setzt globales Interrupt enable
86
  
87
88
  // Timer1 init
89
  
90
  TCCR1B  = (1 << CS10) | (1 << CS11);   // Prescaler 64, Noise Canceler enable
91
  TIMSK1  = (1 << TOIE1);        // Timer1 16-bit Overflow Interrupt enable
92
  TCNT1 = 0;                // Timer1 16-bit bei 0 starten
93
  
94
95
  // INT0 init
96
  
97
  MCUCR  = (1 << ISC01);          // Interrupt bei fallender Flanke
98
  GIMSK  = (1 << INT0);          // Interrupt an INT0 enable
99
  
100
}

von g457 (Gast)


Lesenswert?

Strom vom Bordnetz? Dann [1].

HTH

[1] http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.23

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:

> Hat jemand eine Idee, woran das liegen könnte bzw. was man dagegen
> machen kann?

Unzureichend gesiebte Versorgungsspannung. Die Lichtmaschine deines 
Motorrades bzw. sonstige Dinge im Stromkreis veranstalten ein wahres 
Feuerwerk auf der Versorgungsspannung.

Was hast du denn unternommen um deinen µC vor Störungen auf der 
Versorungsspannung zu schützen?

von David (Gast)


Lesenswert?

Hallo,

zunächst eine Diode 1N4007 - Spule 68µH - 100µF Elko - 100nF Kondensator 
- Spannungsregler 7805 - 100nF Kondensator.
So ist meine Beschaltung, um die Spannung auf 5V zu halten.

von space (Gast)


Lesenswert?

'nabbend,

hoffentlich befindet sich das "Netzteil" direkt am Controller.

Mit den Reed-Kontakten wirst Du noch Spass bekommen:
-das sind mechanische Bauelemente und unterliegen mechanischem
Verschleiss
-mechanische Bauelemente haben eine maximale Schaltfrequenz, die
sich auf die Lebensdauer negativ auswirkt

Sind die Leitungen zum Reed-Kontakt verdrillt oder abgeschirmt?
Wenn nicht, solltest Du das DRINGEND machen. Die Leitungen wirken
prima als Antennen.

Viel Spass

Stefan

von David (Gast)


Lesenswert?

Hallo,

also ich habe testweise noch statt dem 100µF ein 470µF Kondensator 
eingelötet mit gleichem Ergebnis. Auch ein 10µF nach dem Spannungsregler 
zusätzlich brachte keine Änderung.
Das "Netzteil" ist ziemlich dicht am µC, was die Leiterplatte eben 
zugelassen hat. Am µC selbst ist ein 100nF zwischen Vcc und GND.
Es sind normale Litze Leitungen, die ich momentan für den Reedkontakt 
verwende.

Gibt es eine Möglichkeit so etwas softwaremäßig zu unterbinden?

von David (Gast)


Lesenswert?

Guten morgen,

was ich noch Ergänzen möchte bzw. wir aufgefallen ist:
Selbst wenn ich den Reed Kontakt nicht angelötetet habe an die Platine, 
blinkt oder leuchtet die LED auf --> Es sind dann auch keine "Leitungen" 
als Antenne vorhanden.

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:

> Selbst wenn ich den Reed Kontakt nicht angelötetet habe an die Platine,
> blinkt oder leuchtet die LED auf --> Es sind dann auch keine "Leitungen"
> als Antenne vorhanden.

Das unterstützt eigentlich die Theorie, dass die Störungen über die 
Versorgungsspannung reinkommen.

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:
> Hallo,
>
> also ich habe testweise noch statt dem 100µF ein 470µF Kondensator
> eingelötet mit gleichem Ergebnis.

Mach noch kleinere dazu.
Große Elkos können große Störungen auffangen, aber für kurze Spikes sind 
sie zu träge.

> Gibt es eine Möglichkeit so etwas softwaremäßig zu unterbinden?

Ne. Die Versorgungsspannung muss stehen.
Du kannst an deinem Motorrad Elektronik anbringen soviel du willst. Wenn 
du Dreck im Vergaser hast, wird der Motor stottern, egal was du an 
Motorsteuerungselektronik mit hast.

von David (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das unterstützt eigentlich die Theorie, dass die Störungen über die
>
> Versorgungsspannung reinkommen.

Und wie könnte man diese noch weiter entstören?
Die genannte Beschaltung habe ich schon öfter bei µC's am Motorrad 
verwendet, jedoch keinen INT0 Pin genutzt. Da hat es einwandfrei 
funktioniert.

Den Kontakt kann ich auch nicht pollen oder, da er letztendlich vom 
Radumfang nur ein Bruchteil ausmacht und somit ist er schlecht in einer 
zyklischen Abfrage zu "erwischen". Oder habe ich einen Denkfehler?

von byte (Gast)


Lesenswert?

1. Mit Oszi Messen, nur dann kannst sicher was über die 
Versorgungsspannung sagen.
2. Schaltplan/Bilder währen hilfreich.. evtl auch ein Foto der Schaltung 
am Bike.

Wo greifst du deine Potentiale/Masse am Bike ab? Deine Störungen kommen 
mit sehr großer Warscheinlichkeit von der Zündung. Die Frage ist nur.. 
past was mit deiner Entstörung ned, ist die Anordung allgemein ungünstig 
plaziert oder ist was am Bike kaputt. (allgemeine Entstörung)

von David (Gast)


Angehängte Dateien:

Lesenswert?

Hallo byte,

der Schaltplan ist im Anhang.
Das ganze ist auf einer Lochrasterplatine aufgebaut, aber die 
Versorgungsspannung so dicht wie möglich am µC.
Ich wollte erstmal die Signalerkennung ordentlich einlesen, erst dann 
mit der Auswertung und dem Display weitermachen. Jedoch ohne diese 
Grundlage, ist der Rest hinfällig, daher ist der Schaltplan im Moment 
nur minimal.

von Karl H. (kbuchegg)


Lesenswert?

Ich denke als erstes sollte man mal rausfinden, was da im µC eigentlich 
abläuft. Fängt sich der Pin Störungen ein oder wird der ganze µC 
resettet.

Dazu würde ich vorschlagen, das Programm erst mal extrem abzuspecken :-)
1
#include <avr/io.h>
2
#include <utils/delay.h>
3
4
int main()
5
{
6
  DDRA = ( 1 << 6 ) | ( 1 << 5 );
7
  PORTA = 0;
8
9
  while( 1 ) {
10
    PORTA ^= 1<<6;
11
    _delay_ms( 500 );
12
    PORTA &= ~(1<<5);
13
  }
14
}

Das würde ich mal auf den µC brennen.
Engine start und nachsehen was die LEDs machen.

  LED 6    blinkt einmal / Sekunde
  LED 5    geht bei Programmstart an und wird nach dem ersten Blinker
           abgeschaltet

So sollte das sein.
Ist die Blinkfrequenz an LED 6 unregelmässig, bzw. leuchtet auch LED 5 
sporadisch auf, dann wird der µC durch Störungen komplett ausser Tritt 
gebracht und resettet sporadisch.

Das würde mir dann als Nachweis genügen, dass an der Versorgungsspannung 
was getan werden muss.

Verhalten sich die LED aber wie programmiert, dann liegt das Problem bei 
dem einen Eingang (oder im original Code).

Das wäre für mich jetzt erst mal das erste was ich aussortieren würde.

von Karl H. (kbuchegg)


Lesenswert?

Da seh ich noch was.
Probier mal einen kleinen Kondi an Reset, der kurze Spikes auffängt.

von byte (Gast)


Lesenswert?

Reset offen? Offene "Beinchen" können bei sowas fatale Folgen haben. 
Alles am besten nach Datenblatt fachgerecht festnageln (GND, 
Pullup/down, was auch immer).

von Basti (Gast)


Lesenswert?

Jep gerade bei Automotive-anwendungen bau ich immer einen 10k 
pullup+100nF an Reset, bewirkt echt Wunder. Den Eingang hast du ja schon 
entprellt.

von David (Gast)


Lesenswert?

Hallo,

ersteinmal vielen lieben Dank, für die tolle Resonanz in dem Forum, dass 
sich so viele "kostenlos" diesem Problem annehmen und helfen.
Ich bin momentan noch auf der Arbeit, während meine Schaltung zu Hause 
einen auf Harz IV macht und hingegen nicht arbeitet :o)
Wenn ich zu Hause bin, werde ich von Reset nach GND noch einen 100nF 
anlöten und mal das Programm von Karl Heinz aufspielen.
Das Ergebnis werde ich hier dann umgehend berichten.

byte schrieb:
> Reset offen? Offene "Beinchen" können bei sowas fatale Folgen haben.

Der Reset liegt über ein Pullup nach Vcc, also offen ist er nicht. Nur 
der angesprochene Kondensator fehlt.

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:

> Wenn ich zu Hause bin, werde ich von Reset nach GND noch einen 100nF
> anlöten und mal das Programm von Karl Heinz aufspielen.

Wenns dir nicht zu viel Arbeit macht, könntest du die Reihenfolge 
umdrehen? Zuerst Programm ausprobieren und erst dann den C ergänzen.

Wäre interessant
* ob der µC wirklich resettet wird
* ob der C einen Unterschied macht.

Dazu musst du aber den Zustand bei unveränderter Hardware kennen.

Nichts ist so schlimm, wei x Veränderungen gleichzeitig machen und 
hinterher nicht wissen, was den Unterschied ausmachte.

von David (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenns dir nicht zu viel Arbeit macht, könntest du die Reihenfolge
>
> umdrehen? Zuerst Programm ausprobieren und erst dann den C ergänzen.

Nein, das ist doch kein Problem. Die Reihenfolge ist mir egal, solange 
es anderen hilft mir zu helfen und ich anderen dadurch weniger Arbeit 
machen kann :-)

von David (Gast)


Lesenswert?

Hallo zurück,

ich habe nun folgendes ausprobiert:
1. Das Programm von Karlheinz läuft problemlos, blinkt konstant durch 
ohne Störungen --> Die Spannungsversorgung dürfte also passen
2. Der zusätzliche 100nF von Reset nach GND hat (daher vermutlich) auch 
keine Veränderung bewirkt.

Demnach muss es wohl am Code oder an einer Störung des INT0 Pins liegen.

Prinzipielle Frage:
Der Reedkontakt wird ja mittels Widerstand und Kondensator entprellt (+ 
Schmitt Trigger im AVR selbst). Muss/soll man dann zusätzlich den Pullup 
anschalten?
Ich habe mit und ohne versucht, beides mit gleichem Ergebnis, aber was 
davon ist üblich/richtig?

Nun stehen wir wohl wieder am Anfang und können nur sagen, dass es wohl 
nicht an der Spannungsversorgung liegt.

von David (Gast)


Lesenswert?

David schrieb:
> Den Kontakt kann ich auch nicht pollen oder, da er letztendlich vom
> Radumfang nur ein Bruchteil ausmacht und somit ist er schlecht in einer
> zyklischen Abfrage zu "erwischen". Oder habe ich einen Denkfehler?

Guten Abend zusammen,

für mich steht diese Frage immernoch im Raum als alternative Lösung.
Angenommen mein Felge ist 17", macht 1,355m Radumfang. Rechnen wir mit 
1,5m, da der Reifenhöhe auch noch mit einfließt beim abrollen.
Angenommen ich fahre max. 200km/h, entspricht 55,5 m/s. Damit erhalte 
ich ca. eine Frequenz von 37Hz (Pi mal Daumen).
Mein Reedkontakt würde also bei 200km/h 37 mal pro Sekunde betätigt 
werden. Die Schaltzeit inkl. Prellzeit beträgt laut Datenblatt 0,5ms.
Nun ist der Reedkontakt vll. 1cm breit, wo er auf den Magnet reagiert. 
Der die restlichen 135cm des Radumfangs wird der Reedkontakt nicht 
betätigt. Demnach ist die Periodendauer, wo der Reedkontakt betätigt 
ist, sehr gering.
Schaffe ich das mit Polling? Und wenn ja, mit welcher zyklischen Zeit 
wäre das zu pollen (im Hinterkopf habe ich 2xFrequenz).

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:

> für mich steht diese Frage immernoch im Raum als alternative Lösung.
> Angenommen mein Felge ist 17", macht 1,355m Radumfang. Rechnen wir mit
> 1,5m, da der Reifenhöhe auch noch mit einfließt beim abrollen.

ok

> Angenommen ich fahre max. 200km/h, entspricht 55,5 m/s. Damit erhalte
> ich ca. eine Frequenz von 37Hz (Pi mal Daumen).

ok

> Mein Reedkontakt würde also bei 200km/h 37 mal pro Sekunde betätigt
> werden.

ok

> Die Schaltzeit inkl. Prellzeit beträgt laut Datenblatt 0,5ms.
> Nun ist der Reedkontakt vll. 1cm breit, wo er auf den Magnet reagiert.
> Der die restlichen 135cm des Radumfangs wird der Reedkontakt nicht
> betätigt. Demnach ist die Periodendauer, wo der Reedkontakt betätigt
> ist, sehr gering.

Du hast sooo gut angefangen.
Und jetzt hörst du mitten drin auf zu rechnen.

Mit 'sehr gering' kann man keine Aussagen treffen.

Dein Rad dreht sich 37 mal in der Sekunde. D.h. alle 1/37 Sekunde kommt 
der Kontakt wieder vobei.

Der Kontakt wird nich am äusseren Ende des Rades angebracht sein, 
sondern irgendwo in der Mitte, Sagen wir bei einem Radius von 1m. D.h. 
bei einer Umdrehung spulen sich wieviele cm in dieser 1/37 Sekunde 
durch? Dann kann man im Umkehrschluss ausrechnen, wie lange dieser 1cm 
lange Kontakt braucht, um am Sensor vorbeizuhuschen.

Und das ist dann die Zahl, die du brauchst: Wie lang ist der Kontakt im 
SIchtfeld des Sensors.

von Björn R. (Gast)


Lesenswert?

Moin,
Polling ist doch scheisse! Das muss auch mit dem Interrupt 
funktionieren. Da muss einen doch der Ehrgeiz mal packen! Hast du ein 
oszilloskop, mit dem du mal nachschauen kannst, was auf deinem INT0-Pin 
so alles ankommt?

LG, Björn

von David (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Der Kontakt wird nich am äusseren Ende des Rades angebracht sein,
> sondern irgendwo in der Mitte, Sagen wir bei einem Radius von 1m. D.h.
> bei einer Umdrehung spulen sich wieviele cm in dieser 1/37 Sekunde
> durch? Dann kann man im Umkehrschluss ausrechnen, wie lange dieser 1cm
> lange Kontakt braucht, um am Sensor vorbeizuhuschen.

Ich nehme an, du meinst folgerichtig Umfang 1m, nicht Radius :-)
1m = 100cm, sodass 100cm/37Hz = 2,70cm (+zerquetschte) bewegen sich also 
in einer 1/37 Sekunde vorbei.
Nehme ich nun der Einfachheit wegen 3cm an, so müsste ich bei 1cm 
Reedbreite 3*37Hz als Frequenz nehmen bzw. um alle zu erwischen, sagt 
man ja, doppelte Abtastrate 2*3*37Hz = 222Hz, was ca. 0,45ms entspricht.
In dieser Zeit müsste ich also den Kontakt pollen. Richtig?

Björn R. schrieb:
> Moin,
> Polling ist doch scheisse! Das muss auch mit dem Interrupt
> funktionieren. Da muss einen doch der Ehrgeiz mal packen! Hast du ein
> oszilloskop, mit dem du mal nachschauen kannst, was auf deinem INT0-Pin
> so alles ankommt?

Hallo Björn,

leider nein. Mich hat zwar der Ehrgeiz gepackt, aber ich weiß einfach im 
Moment nicht weiter, sodass ich nach Alternativen Ausschau halte. Da ich 
erst seit ca. 3-4 Monaten mich mit µC beschäftige, habe ich auch nicht 
so die Erfahrung, um mögliche Fehler zu erkennen.
Alle Ideen hier im Forum habe ich erfolglos versucht umzusetzen :(

Testweise habe ich heute auch den INT Pin mal als Ausgang gesetzt und 
versucht. Das INT reagiert ja auch, wenn der Portpin als Ausgang 
definiert ist. Dies blieb jedoch auch ohne erfolg. Auch habe ich mal die 
100nF durch 1µF ersetzt, um vielleicht so durch einen anderen Tiefpass 
diese seltsamen Interrupts wegzubekommen, auch ohne erfolg...

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:
> Karl heinz Buchegger schrieb:
>> Der Kontakt wird nich am äusseren Ende des Rades angebracht sein,
>> sondern irgendwo in der Mitte, Sagen wir bei einem Radius von 1m. D.h.
>> bei einer Umdrehung spulen sich wieviele cm in dieser 1/37 Sekunde
>> durch? Dann kann man im Umkehrschluss ausrechnen, wie lange dieser 1cm
>> lange Kontakt braucht, um am Sensor vorbeizuhuschen.
>
> Ich nehme an, du meinst folgerichtig Umfang 1m, nicht Radius :-)
> 1m = 100cm, sodass 100cm/37Hz = 2,70cm (+zerquetschte) bewegen sich also
> in einer 1/37 Sekunde vorbei.

Äh nein.
Wenn Der Kreis, auf dem der Kontakt sitzt, 37 Umdrehungen pro Sekunde 
macht, und der Kreis 100cm Umfang hat, dann können nicht 2.7 cm in 1/37 
Sekunden vorbeirauschen, sondern logischerweise 100cm pro 1/37 Sekunde

> Nehme ich nun der Einfachheit wegen 3cm an, so müsste ich bei 1cm
> Reedbreite 3*37Hz als Frequenz nehmen bzw. um alle zu erwischen, sagt
> man ja, doppelte Abtastrate 2*3*37Hz = 222Hz, was ca. 0,45ms entspricht.
> In dieser Zeit müsste ich also den Kontakt pollen.

Den Rechengang hab ich jetzt nicht verstanden

    100 cm                1/37 Sekunde
      3 cm                  x
   -------------------------------------

             1
           ----  * 3
            37                   3
     x =  --------------  =  -----------  = 0.00081 Sekunden = 0.8 ms
               100             37 * 100


Läuft der µC mit 1Mhz heist das, du hast 800 Takte Zeit um die 
Veränderung zu detektieren. 800 Takte sind ~600 bis 700 Assembler 
Befehle.

von David (Gast)


Lesenswert?

Stimmt. Allerdings habe ich wohl mit dem 3cm aus der vorherigen Rechnung 
auch wieder Verwirrung gestiftet, der Reed Kontakt ist ja nur 1cm breit.
Demnach 1/3700 = 0,27ms
Wenn ich jetzt noch die Abtastrate mit einrechne von 2, wäre ich bei 
0,135ms.
Der µC läuft mit 8Mhz (interner Oszillator).
Macht das überhaupt Sinn dann zu pollen? Der µC soll ja später auch noch 
andere Aufgaben erledigen, als nur dieses Kontakt abzufragen.

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:
> Stimmt. Allerdings habe ich wohl mit dem 3cm aus der vorherigen Rechnung
> auch wieder Verwirrung gestiftet, der Reed Kontakt ist ja nur 1cm breit.
> Demnach 1/3700 = 0,27ms
> Wenn ich jetzt noch die Abtastrate mit einrechne von 2, wäre ich bei
> 0,135ms.
> Der µC läuft mit 8Mhz (interner Oszillator).
> Macht das überhaupt Sinn dann zu pollen? Der µC soll ja später auch noch
> andere Aufgaben erledigen, als nur dieses Kontakt abzufragen.

Ein 8-Bit Timer, der mit full Speed taktet, erzeugt dir alle 0.032 ms 
einen Overflow Interrupt :-)

Ich würds aber trotzdem nicht pollen.
Hat dein Tiny keine Input Capture Unit?
Die ist eigentlich prädestiniert für solche Aufgaben.

von David (Gast)


Lesenswert?

Das meinte ich nicht als Problem. Ich könnte auch durch ein CTC ein 
schnelleres Interrupt erzeugen. Mir geht es nur darum, ob ein so schnell 
wiederkehrendes Timer Interrupt nicht soviel Ressourcen verschwendet, 
sodass andere Aufgaben nicht zeitkritisch erledigt werden können.
Angedacht war noch ein Drehzahlmesser über die Input Capture Funktion 
und eben die Ausgabe auf einem LCD der Werte (das wäre weniger 
zeitkritisch).

von Karl H. (kbuchegg)


Lesenswert?

David schrieb:
> Das meinte ich nicht als Problem. Ich könnte auch durch ein CTC ein
> schnelleres Interrupt erzeugen. Mir geht es nur darum, ob ein so schnell
> wiederkehrendes Timer Interrupt nicht soviel Ressourcen verschwendet,
> sodass andere Aufgaben nicht zeitkritisch erledigt werden können.

Dazu musst du überlegen, was denn alles im Interrupt gemahct werden 
muss.
Wichtig: muss! Nicht kann!
Gemacht werden muss: Einen Zähler um 1 hochzählen um die 1 Radumdrehung 
zu registreieren. Was noch? Nichts sonst. Alles andere muss nicht im 
Interrupt gemacht werden.

von David (Gast)


Lesenswert?

Vielen Dank für die aufschlussreiche Hilfestellung.
Ich werde morgen mal versuchen, das wirklich auf das Input Capture 
umzuschreiben.
Den Drehzahlmesser wollte ich über einen Optokoppler einlesen, 
vielleicht stören da die Signale ja nicht und dies wäre dann über das 
INT möglich.

Ansonsten werde ich wohl dann doch pollen, wenn obiges nicht 
funktioniert.

Nochmals vielen Dank und eine gute Nacht :-)

von Thomas Schattat (Gast)


Lesenswert?

Hallo,
habe das mit Interesse gelesen und solche Spielereien schon oft 
erfolgreich gemacht (Motorrad, Reed, IRQ0, Tacho).
Ich bin nicht sicher ob es sinnvoll ist, das Schaltfenster zu messen (so 
hab ich es verstanden). Dieses hängt wohl auch von der Magnetstärke, der 
Trägheit der Kontakte, dem Abstand Magnet-Reed und auch Reed-Radachse ab 
(Stichwort Bahngeschwindigkeit).
Ich habe immer die Umdrehungszeit gemessen, also die Zeit zwischen zwei 
Interrupts. Diese ist von den genannten Faktoren unabhängig und liefert 
ein einwandfreies Ergebnis für Geschwndigkeit und gefahrene Strecke. 
Ausserdem ist die steigende Flanke mit der RC Entprellung auch 
problematisch, es gibt da eine Aufladekurve die das Fenster 
beeinflußt...
Ein Tip: Reed soweit wie möglich zur Radachse hin, da flitzt der Magnet 
am langsamsten vorbei.

Viel Erfolg wünsche ich...

Gruß
Thomas

von David (Gast)


Lesenswert?

Hallo Thomas,

das Programm oben misst auch von fallender zu fallender Flanke und tut 
genau das, was du beschreibst, eben die Zeit zwischen 2 Interrupts zu 
messen.
Dabei wird bei jeder fallenden Flanke eine LED angeschaltet, die bei 
jeder steigenden wieder abgeschaltet wird. Daher ist die Zeit, wann die 
steigende Flanke auftritt, unkritisch, da diese nur die LED abschaltet, 
aber nichts mit der Messung zu tun hat.
Die LED dient nur zum sehen, ob der Reedkontakt noch sauber arbeiten und 
schaltet bzw. wann er schaltet (gerade bei der Testphase vom Programm 
sehr hilfreich).
Der Kontakt hat einen sehr geringen Abstand und schaltet ja auch. Es ist 
nur das Problem, dass die Interrupts von selbst ausgelöst werden, auch 
wenn ich den Reedkontakt ablöte, auch dessen Anschlüsse.
Irgendetwas von der Bordelektronik stört und zieht den Pin INT0 auf 
Masse.
Deshalb war die Idee mit dem Schaltfenster als alternative angedacht, da 
ich das mit der seltsamen Eigenauslösung am INT0 nicht auf die Reihe 
bekomme.

Die Umdrehungszeit hängt aber sehr wohl vom Raddurchmesser bzw. 
Abrollumfang ab (beim Fahrradtacho muss ja auch die Reifengröße 
einstellen).
Hast du mit solchen Problemen zu kämpfen gehabt? Das sich das INT0 ohne 
Schließung des Reed Kontaktes sporadisch selbst auslöst?

von Thomas Schattat (Gast)


Lesenswert?

Hallo David,
OK, dann hatte ich das falsch verstanden. Ich habe da keine Probleme mit 
"Selbstauslösern". Klar ist der Radumfang entscheidend, ich habe in 
meinen Geräten den mit 2160mm eingestellt und änderbar gemacht (21 Zoll 
Geländereifen). Bin damit 7000km Africarace von Marseille nach Dakar 
letztes Jahr gefahren, ohne Theater!!
Haste mal versucht das mit einer Batterie testweise ohne Bordspannung zu 
betreiben?
Ich habe bei mir eine Batterie drin (4,5V) und parallel mit Dioden 
entkoppelt einen 7805 mit 100nF vorn und hinten und einem 100 Ohm 
Vorwiderstand und noch einem 10µF Elko am Eingang. Hatte Angst vor 
irgendwelchen Spikes die da im Bordnetz auftauchen könnten. Funktioniert 
immer ohne Problem, Prozessor ist ein Atmega162.
Ich bin in Hofheim zwischen Wiesbaden und Frankfurt. Wenn du kein 
Oszilloskop hast kannste gerne mal vorbeikommen, ich bin da gut 
ausgestattet.
Wenn es auch ohne Reedkabel von allein auslöst weiß ich es auch nicht, 
ein Test mit separater Batterie wäre mein nächster Versuch.

Gruß
Thomas

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.