mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Fehlersuche.bekomms echt nicht hin


Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend zusammen,

Eigentlich sehr leicht das Programm aber ich bekomm es nicht zum Laufen

$regfile = "m32def.dat"
$framesize = 128
$swstack = 128
$hwstack = 128
$crystal = 8000000
$baud = 9600
$lib "glcdKS108.lib"

Config Timer1 = Timer , Prescale = 8
Enable Timer1
On Timer1 Auswertung
Timer1 = 55535
Enable Interrupts

Config Int2 = Falling
Enable Int2
On Int2 Check

Dim Cnt As Integer , Cntalt As Integer
Dim Umfang as Integer, Ms as Integer
Umfang = 1850



Do
Ms=Umfang/cntalt
Lcdat 5,20,Ms
wait 1
Loop
End

Check:
Cntalt = Cnt
Cnt = 0
Return

Auswertung:
Timer1 = 55535
Cnt = Cnt + 1
Return



Ich bekomme als Displayausgabe immer "0" angezeigt. Sobald ich cntalt 
durch cnt ersetze, bekomme ich das richtige ergebnis. Was ist falsch?

Mfg

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Was hängt den an deinem INT2. Falls das ein Schalter ist, besteht die 
Möglichkeit, das dein cntalt überschrieben wird, bevor es die Ausgabe 
erreicht.

MfG Spess

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da hängt ein Tacho- Impulsgeber dran der, sobald der Magnet dran 
vorbeigeht einmal schaltet,also warscheinlich nix anderes als ein 
Schalter

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Wenn das Teil prellt, also mehrmals kurz hintereinander schaltet wird 
jedes mal 'Check' aufgerufen. Beim ersten mal wird cnt=0. Das bekommt 
beim zweiten Mal dein 'cntalt' und ist Null.

MfG Spess

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm das könnte sein aber warum geht es dann wunderbar, wenn ich statt 
cntalt cnt verwende? das müsste doch die selben Werte annehmen

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

> das müsste doch die selben Werte annehmen

Gute Frage. Aber kurz nach dem Prellen schlägt dein Timerinterrupt 
wieder zu. Ich bin nicht sehr firm in BASCOM und der Zweck deines 
Programms entzieht sich mir auch etwas. Aber wenn ich davon ausgehe, das 
dein Timerinterrupt der Overflowinterrupt mit einem Preload von 55535 
ist, sollte der alle 10ms kommen. Wenn der Abstand der INT2-Auslösung >> 
10ms ist, wirst du durchaus logische Werte bekommen.

MfG Spess

P.S.  '>>' als 'gross gegen ' interpretieren.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unterscheidet BASCOM Gross- und kleinschreibung bei den Variablen? Bei 
den Line Labels tut es das nicht, bei den Variablen finde ich keine 
Angabe im Manual. Nur wegen diesem Punkt:
> Dim Cnt As Integer , Cntalt As Integer
> Ms = Umfang / *cntalt*

Ich versuche mal zu verstehen, was das Programm macht:

Auswertung: Timer1 Overflow tritt alle 10ms auf. Die Zahl der Overflows 
wird in Cnt gezählt.

Check: Bei einer fallenden Flanke soll INT2 ausgelöst werden. Beim INT2 
wird die Anzahl der Overflows in Cntalt gesichert und Anzahl der 
Overflows zurück gesetzt. Wenn dein INT2 nicht funktioniert 
(Initialisierung OK? Hardware OK? Eine Debug-LED im INT2 toggeln wäre 
jetzt schlau!), dann bleibt Cntalt immer 0...

Hauptprogramm: Ms = 1850 / (Anzahl Overflows von fallender Flanke zu 
fallender Flanke).

Wenn nur ein Geber an dem Rad ist, entspricht die Zeit zwischen 2 INT2 
einer Radumdrehung. Die Zeit zwischen zwei INTs ist die Anzahl Ticks der 
10ms Uhr (cntalt). Wenn die Wegstrecke einer Radumdrehung bekannt ist 
(Umfang 1850) ergibt sich die Geschwindigkeit durch Umfang dividiert 
durch Anzahl der 10ms Ticks.

Das Messverfahren ist so nur möglich, wenn eine geradzahlige Anzahl von 
INT2 gemessen wurden ("von Flanke zu Flanke"). In der Zeit vor der 
ersten Flanke ist Cntalt = 0, d.h. Division durch Null bei Ms=... Die 
Auswertung ist sinnlos. In der Zeit zwischen erster Flanke und zweiter 
Flanke ist Cntalt die zufällige Anzahl der Overflows bis zur ersten 
Flanke. Die Auswertung ist sinnlos. In der Zeit nach der zweiten Flanke 
vor der dritten Flanke, kann die Geschwindigkeit zur Zeit der vorherigen 
Umdrehung sinnvoll berechnet werden...

Die Genauigkeit kann gesteigert werden, wenn zusätzlich der Zählerstand 
in TCNT1 berücksichtigt wird. Derzeit kann der Startwert und der Endwert 
der Zeitmessung je maximal 10ms daneben liegen. In Summe also 
Maximalfehler 20ms bzw. zwei Ticks.

Rein aus Neugier - Mit welchen wahnsinnigen Geschwinigkeiten gehst du da 
um?

Vmax: 1850/1 => 1 Umdrehung/(1*10ms) => 1850 m/s => 6660 km/h
Vmin (Grenze ist Überlauf in den Integervariablen Cnt und Cntalt): 1 
Umdrehung/(32767*10ms) => 1 Umdrehung / ca. 5,5 Min. => 20,3 km/h

Für's Fahrrad wäre das anspruchsvoll: Beim Testen musst du ordentlich in 
die Pedale treten ;-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Was macht 'wait 1'?

MfG Spess

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. wrote:

> Vmin (Grenze ist Überlauf in den Integervariablen Cnt und Cntalt): 1
> Umdrehung/(32767*10ms) => 1 Umdrehung / ca. 5,5 Min. => 20,3 km/h

Korrektur:
Wenn deine Formel genommen wird gilt Vmin = 1850/32767 => 0,2 km/h

Der Messbereich wäre so OK. Entwarnung du brauchst nicht so stark zu 
strampeln!!!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 wrote:

> Was macht 'wait 1'?

ca. 1 Sekunde in Software d.h. ohne Timer warten. Quasi ein 
_delay_ms(1000).

*BASCOM AVR Manual*
http://avrhelp.mcselec.com/index.html

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-D nich schlecht nich schlecht=)
Nein die geschwindigkeit sollte eig. im Bereich von 0-200 Km/h liegen 
und das soll ein Tacho für mein Motorrad werden. Das problem wa sih 
vorher hatte war, dass ich den Cnt nie richtig auswerten konnte, da 
dieser erst immer nach einer Sekunde ausgewertet wurde (Wait 1 in der 
Main). Daher konnte der Cnt auch rein zufällig grade wieder "0" sein, 
und die Auswertung sinnlos. Deshalb wollte ich den letzt hövhsten Wert 
speichern (cntalt) und das ergebnis mit diesem Auswerten. ALso hab ich 
mir obrigen Programmcode ausgedacht, der leider nicht das tat was er 
tuen sollte=). Im Normalfalle sollte der cnt nicht den Wert 1 erreichen, 
sodass keine Km/h von 6600 möglich ist. Das Programm ist leider noch 
nicht ausgereicft, da ich noch vor den "Stadartproblemen" stehe, Für 
Anregungen bin ich dankbar=). Das Wait 1 soll mir einfach nur das 
Display nach einer Sek aktualisieren. TCNT1 sagt mir nix sorry. Aber 
warum kann das Ergebnis nur stimmen, wenn eine grade Anzahl von INT2s 
vorhanden ist? INT2 soll doch nur die Zeit für eine Radumdrehung 
ermitteln. ALso ist INT2 doch immer "1" oder nicht?

Mfg

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stephan B.

Werden die Interrupts nich TROTZ wait eingeleitet? Wenn nich dann sry 
(weis es nicht besser, meine das nur so verstanden zu haben:))

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch doch. Das WAIT ist "schwächer" als der Timer1. Der Timer1 und der 
INT2 unterbrechen WAIT, wenn es sein muss. Daher ist WAIT nicht genau. 
Das ist hier aber egal.

TCNT1 ist der Timer1 Zähler, der bei dir von 55535 bis 65535 hochgezählt 
wird und dann den Overflow auslöst. Im Extremfall sind das ja auch noch 
10000 Takte Messzeit. Der Name steht auch so im Datenblatt des AVRs.

1. KEIN INT2 aufgetreten:
In der Zeit vor der ersten Flanke ist Cntalt im Programm 0, d.h. 
Division durch Null bei Ms=... Die Auswertung ist sinnlos.

2. EIN INT2 aufgetreten:
In der Zeit zwischen erster Flanke und zweiter Flanke ist Cntalt die 
zufällige Anzahl der Overflows bis zur ersten Flanke. Die Auswertung ist 
sinnlos.

3. ZWEI INT2 aufgetreten:
In der Zeit nach der zweiten Flanke vor der dritten Flanke, kann die 
Geschwindigkeit zur Zeit der vorherigen Umdrehung sinnvoll berechnet 
werden...

4. DREI (und folgende) INT2 aufgetreten:
Hast Recht! Sorry. Unschön ist das Verhalten beim Stehenbleiben. Die 
Anzeige geht nicht auf 0 zurück.

Bau dir unbedingt zum Debuggen was ein, das dir anzeigt, ob die INT2 
auch wirklich kommen. Meine erste Idee war eine LED toggeln. Du kannst 
auch eine Variable in Check hochzählen, auf dem LCD anzeigen und die 
Zahl mit den manuellen Radumdrehungen vergleichen. Dann siehst du, ob 
Prellen stattfindet und ob du was dagegen machen musst.

Später, solltest du dir mal den Artikel Drehgeber ansehen und welche 
Haken bei der "billigen" Auswertung mit Flankenerkennung auftreten 
können.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. G. wrote:

Diese Abfolge gefällt mir noch nicht:

> Config Timer1 = Timer , Prescale = 8
> Enable Timer1
> On Timer1 Auswertung
> Timer1 = 55535
> Enable Interrupts
>
> Config Int2 = Falling
> Enable Int2
> On Int2 Check

Logischer ist alles vorzubereiten und dann erst die Interrupts 
einzuschalten.

Config Timer1 = Timer , Prescale = 8
On Timer1 Auswertung
Timer1 = 55535
Enable Timer1
Config Int2 = Falling
On Int2 Check
Enable Int2
Enable Interrupts   ' ab hier laufen Timer1 und Int2 tatsächlich

Autor: M.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja dass die Anzeige noch nicht zurückgeht hat mich auch schon 
beschäftigt aber da werd ich mir schon noch was ausdenken=). Der INT2 
kommt auf jeden fall bei jeder Umdrehung das hab ich schon alles 
ausprobiert. Werd mich später mal mit dem Drehgeber beschäftigen. Erst 
mal vielen Dank vllt bekomm ichs ja noch ans Laufen. Sonst meld ich mich 
noch mal

Mfg

Autor: M.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach folgendes: Wenn ich einen 10ms Interrupt nehme habe ich bei hohen 
Geschwindigkeiten riesen Sprünge richtig? Hab mal nachgerechnet bei 30ms 
fahre ich 222km/h, bei 40ms jedoch nur 166.5 km/h! Also wäre doch eine 
Teilung von 10ms viel zu wenig oder? Mit 1ms habe ich bei hohen 
Geschwindigkeiten aber auch Sprünge von ca. 8 km/h (33ms = 201 km/h, 
32ms = 208 km/h). Also sollte ich mir was komplett neues ausdenken 
richtig? Meine Maschine schafft zwar keine 200km/h aber kleinere Sprünge 
sind ja auch unter 200 km/h vorhanden.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also sollte ich mir was komplett neues ausdenken richtig?
Wie wäre es, die Zeit zwischen zwei Tacho-Impulsen mit einem 16 
Bit-Timer (also Hardware) zu messen?
1. Impuls --> Timer auf 0 setzen und starten
2. Impuls --> Timerwert auslesen und weiterverarbeiten
3. Impuls siehe 1. Impuls

Autor: M.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann müsste ich nur ermitteln was für eine Zeit dem Zählerwert 
entspricht richtig? Bzw. bei 8Mhz Quarz weis ich doch dass der Timer 
8Mhz Takte in der Sekunde rausgibt und kann das danach auswerten

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ M.G.

Stimmt.

Radumfang: 1,85 m
Radradius: 0,294 m (= 1,85m/(2*Pi))

Tatsächliche Geschwindigkeit:

200 km/h = 55,6 m/s
1,85 m / 55,6 m/s = 0,0333 s => 33,3 ms pro Radumdrehung

Gemessene Geschwindigkeit:

33,3ms liefert 3 Ticks (10ms Overflows). 3,3ms werden durch das 
Messverfahren der Oberflows alleine nicht berücksichtigt. Sie stecken 
aber auslesbar im Timer1 Register!

1,85m / 0,03s = 61,7 m/s = 222 km/h

Werte unbedingt in Check nicht nur die Zahl der Overflows sindern auch 
noch den Stand in Timer1 aus! Im Detail brauchst du die Zahl der im 
Timer1 bereits abgeleisteten Takte seit der letzten Initialisierung auf 
55535
, also (Timer1Istwert-55535). Die komplette Formel sieht dann so aus:

Ms = 1,85 / ((0,01 * Cntalt) + ((Timer1Istwert-55535) * 0,01/10000))

BTW: Ist eigentliche Problem schon gelöst?
> Ich bekomme als Displayausgabe immer "0" angezeigt.

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey super schon mal vielen Dank für die Rechnung=). Nein das mit der 
Displayausgabe ist leider immer noch nicht weg :/

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hab grad festgestellt dass ich schonmal bei einem INT2 Interrupt zwei 
mal in die Check schleife komme. Der Interrupt wird also beim 
vorbeiführen des magneten zwei mal ausgelöst, was schon mal blöd ist. 
Daher ist cntalt auch "0", da er direkt mit dem zweiten Interrupt 
überschrieben wird, welcher "0" ist

Autor: M.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn ich mit Integer rechne (Also alles as Integer definiert) hab 
ich keine Probleme mit der Anzeige. Sobald ich aber die Variablen als 
Single definiere, bekomme ich immer probleme bei der Displayausgabe. 
Liegt das an den langen Rechenzeiten mit Single?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, die lange Rechenzeit wird in den Interruptroutinen Check und 
Auswertung kritisch sein. Wie sieht es aus, wenn du nur Ms als Single 
definierst? In dem Hauptprogramm ist die Rechenzeit fast egal (zur Not 
WAIT durch WAITMS ersetzen und dabei Wartezeit verkürzen).

Dim Ms as Single
Dim Umfang as Integer
Umfang = 1850

' ### Hauptprogramm ###
  Do
    Ms = Umfang
    Ms = Ms / Cntalt
    Lcdat 5, 20, Ms
    Wait 1
  Loop
End

Autor: M.G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werd ich nachhher mal ausprobieren. Dachte es ist egal, wo ich die Daten 
für Ms ausrechne...hab die bis jetzt immer in den Interrupts 
ausgerechnet. Mal schauen vllt gehts ja mit der Hauptschleife=)

Autor: M. G. (sirmel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So klappt alles wunderbar vielen Dank für eure Hilfe Leute, vorallem @ 
Stefan B. :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.