Forum: Mikrocontroller und Digitale Elektronik Mega8 Temperatur Drehzahlregler


von Sebastian (Gast)


Lesenswert?

Hallo,

ich möchte gerne ein Projekt realisieren und weiß nicht genau wie ich 
anfangen soll.Ich möchte gerne mit dem Mega8 einen Computerlüfter 
Steuern und ein Relais.Das Relais soll eine Wärmeplatte 
ein/ausschalten.Die Temperatur soll mit einen Sensor kontrolliert 
werden.Der Lüfter soll Drehzahlgesteuert sein.Das ganze möchte ich mit 2 
Potis steuern und die eingestellten Werte sollen auf einen LCD 
ausgegeben werden.

Also ich schaffe Werte auf einen LCD auszugeben.Potis mit dem ADC 
auszulesen und den Sensor in Betrieb zu nehmen.Mit der Drehzahlregelung 
weiß ich es jetzt noch nicht,aber das wird wohl mein kleinstes Problem 
sein.

Problem ist jetzt folgendes der ADC so wie ich Ihn bis jetzt erst 
benutzt habe gibt mir Werte von 0-255 (Terminal Programm).Ich möchte 
jetzt aber z.B. meine Wärmeplatte nur von 0-100° einstellen können.Wie 
schaffe ich jetzt das ich nur ein ADC Ergebniss von 0-100 in meinem 
Programm erhalte.Weil dieses möchte ich dann einfach mit dem Ist-Wert 
vom Sensor vergleichen und ein/ausschalten.

Dann wie funktioniert das mit der Drehzahlsteuerung habe so einen Lüfter 
mit dem dritten Kabel dran.

Ich möchte jetzt keinen fertigen Code oder so ich wollte jetzt einfach 
mal eine kleine Starthilfe.

MfG Sebastian

von Joachim B. (jojo84)


Lesenswert?

Ok, das klingt doch alles schonmal nicht schlecht. Daß du Werte auf dem 
LCD dargestellt bekommst ist sehr hilfrech. Das erleichtert das 
Debugging ungemein.
Du siehst im Terminal Werte von 0-255. Das kann entweder bedeuten, daß 
du nur das untere Byte deines 10-bit-Ergebnisses ausgiebst (bei 
rechtsbündiger Anordnung, verlierst du beiden obersten Bits) oder eben 
nur das obere Byte bei linksbündiger Anordnung (verlierst du beiden 
untersten Bits). Der ADC könnte dir ja eigentlich Werte von 0-1023 
liefern. Da du ja recht lernbereit zu sein scheinst (sehr löblich) 
überlasse ich es erstmal dir, wie du das handhabst/hinkriegst.
Jetzt willst du einen Zahlenbereich von 0-100 darstellen. Wenn das ohne 
Kommastellen ablaufen soll, dann ist das ja ganz einfach:
dein ADC gibt Werte raus von 0 bis xxx. Wenn xxx als 1023 angenommen 
wird, dann mußt du also 100 auf 1023 aufteilen.
Wie das geht? 1023 / 100 = 10,23! Was du mit dem Wert jetzt anzustellen 
hast überlasse ich erstmal wieder dir =) .

Zu deinem Lüfter: unterscheide zwischen Steuerung und Regelung. Bei 
einer Steuerung gibst du stumpf einen "Sollwert" vor. Ob dein Lüfter 
jetzt aber wirklich damit läuft weißt du nicht und interessiert dich 
auch nicht.
Bei einer Regelung hast du einen Sollwert, und erhältst über eine 
Messung den Istwert (Drehzahl). Mit den beiden Werten mußt du einen 
Regelalgorithmus füttern (für Anfänger oft nicht ganz einfach). Darum 
solltest du erstmal mit dem "Steuern" der Drehzahl anfangen.
Der Rest ist wieder nur eine Frage der Skalierung. Du weißt z.B.: der 
Lüfter darf maximal 12V. Jetzt kannst du sagen: bei 0°C soll der Lüfter 
stehen, und bei 100°C mit Nenndrehzahl laufen (die Drehzahl bei 12V). 
Also mußt du den Spannungsanstieg pro °C hinkriegen: 12V / 100°C = 0,12 
V/°C. das ist dann aber eine Steuerung, keine Regelung.
Und wenn du das hingekriegt hast, dann reden wir über die Regelung :) 
...

Gruß

von Joachim B. (jojo84)


Lesenswert?

Nachtrag:
wie findet eigentlich deine Temperaturmessung statt? Und willst du 
wirklich eine "Temperaturregelung" haben? Wenn ja, dann brauchst du eine 
Temperaturregelung, der dann noch eine Drehzahlregelung des Lüfters 
unterlagert ist. Da wird es dann schon "interessant".
Falls du es hinkriegst die Werte 0-1023 aus dem ADC zu kitzeln: meinst 
du nicht es wäre sinnvoller, wenigstens in 0,1°C-Schritten zu arbeiten? 
Dann ginge dein Wertebereich von 0-102,3°C in 0,1 Grad-Schritten...

von Sebastian (Gast)


Lesenswert?

Also ich habe gestern noch bis 4 Uhr am Computer gehangen.Und selbst 
herausgefunden das ich den ADC Wert ganz einfach Teilen kann.Ich habe 
den ADC vorher auf 8bit eingestellt gehabt,deswegen waren es nur 0-255 
jetzt läuft er auf 10bit und wird dann geteilt.Ich kann jetzt auch schon 
beide Potis einlesen und den Wert auf den LCD ausgeben.Weil ich jetzt 
noch keinen Sensor hier rumliegen habe,ist ein Sollwert im Programm um 
zu testen ob das Relais schaltet das funktioniert auch.Also ist dieser 
Teil kein Problem mehr für mich.Jetzt hatte ich vor genau wie Du geagt 
hast den Lüfter zu intigrieren.Da bin ich aber noch etwas überfragt wie 
ich das anstelle,weil er ja 12V braucht.Würde er nur 5V brauchen hätte 
ich den irgendwie über PWM gesteuert.Ich brauche zwar eigentlich nur 
etwa die hälfte der möglichen Drehzahl des Lüfters,aber zum anlaufen 
braucht er die 12V danach kann dann sofort runtergeregelt werden.Was 
kann ich jetzt zwischen Lüfter und Mega8 schalten,das Dimmbar ist? Wenn 
ich dann diese Hürde gemeistert habe,wollte ich irgendwie das Signal für 
die Drehzahl über den Timer(Counter) zählen und dann 
weiterverarbeiten.Bin ich auf dem richtigen Weg?Oder kann man das besser 
lösen?

Um zu erläutern warum ich den Temparatur Sensor und die 
Drehzahlsteuerung benötige erkläre ich am besten was ich vor habe.

Ich möchte ein Magnetrührer selber bauen,da anständige Modelle sehr 
teuer sind.Und wirklich viel Elektronik ist da nicht drin.Es wird eine 
alte Warmeplatte benutzt um die Chemiekalien zu erhitzen,der Sensor soll 
eine genaue Gradzahl einstellung ermöglichen.Der Lüfter dreht eigentlich 
nur 2 Magnete.Der Drehzahlbereich sollte zwischen 100-1000rpm liegen.Das 
war es schon.

MfG Sebastian

von Sebastian (Gast)


Lesenswert?

Ich habe gerade wahrscheinlich mal den ganz klassischen Anfänger Fehler 
gemacht.Und zwar wollte ich für die Drehzahlen eine art sagen wir mal 
Tabelle machen um die verschiedenen PWM Signale zu erzeugen.

Das klapte auch aber ich wollte stufenlos Regeln.

Ich habe jetzt noch mal mein kleines Spatzenhirn angestrengt und den 
Wert vom ADC als Wert für den Timer genommen das klapt auch.

So einfach kann es sein!

Jetzt müßte ich nur wissen wie genau die 3 Leitung vom Lüfter 
funktioniert was kommt da für ein Signal raus? Kommt ein Signal für eine 
Umdrehung?

MfG Sebastian

von Joachim B. (jojo84)


Lesenswert?

Moin,

Sebastian schrieb:
> Da bin ich aber noch etwas überfragt wie
> ich das anstelle,weil er ja 12V braucht.Würde er nur 5V brauchen hätte
> ich den irgendwie über PWM gesteuert.Ich brauche zwar eigentlich nur
> etwa die hälfte der möglichen Drehzahl des Lüfters,aber zum anlaufen
> braucht er die 12V danach kann dann sofort runtergeregelt werden.

Es klingt ja ein bißchen so, als ob dir die Hardware ansich etwas 
Probleme bereitet. Um von den 5V aus deinem Controller auf 12V zu kommen 
gibt es ein besonderes Teil: den Transistor :) ! Wie du das Ding dann zu 
verbauen hast steht (nicht nur) hier auf der Seite ganz gut erklärt.

Sebastian schrieb:
> Wenn
> ich dann diese Hürde gemeistert habe,wollte ich irgendwie das Signal für
> die Drehzahl über den Timer(Counter) zählen und dann
> weiterverarbeiten.Bin ich auf dem richtigen Weg?

Ich finde ja :)

Sebastian schrieb:
> Ich möchte ein Magnetrührer selber bauen,

Das check ich nicht. Wie soll den der Lüfter, der die Magnete antreibt, 
die Temperatur beeinflussen? Das ist alles etwas durcheinander. Ich 
dachte die Beeinflussung der Temperatur geschieht über an- und- 
ausschalten der Heizplatte?! Dann wird die Temperatur aber nie "genau" 
sein (Stichwort Zweipunktregler, Hysterese).

Bei den drei Lüfterleitungen kann man so pauschal erstmal nichts sagen. 
Erstmal müßte man wissen, was das genau für ein Lüfter ist. Bei drei 
Leitungen ist es wohl ein ganz normaler/älterer. Die Modernen haben ja 
z.T. vier Leitungen. Versorgung+, Masse, Drehzahlsignal vom Lüfter 
(Ist-Wert) und PWM-Eingang (Sollwert). Wenn du nur drei Leitungen hast 
entfällt der PWM-Eingang.

Mit dem Tachosignal ist das wieder so eine Sache. Das ist bei diesen 
Lüftern nicht wirklich einheitlich. Ich hatte mal einen, der gab alle 
180° einen Puls aus. Aber der Pegel war alles andere als sauber. Wenn du 
das genau wissen willst hilft nur ein Scope.

Also, du hast zwei Sollwerte:
1. Drehzahl der Rührers (hat erstmal mit der Temperatur nichts zu tun!)
2. Soll-Temperatur

Temperaturregler sollte kein Problem sein: PLatte an, Platte aus 
(Hysterese).
Bei der Drehzahl: willst du die wirklich "regeln"? Reicht es nicht die 
Drehzahl von 0-100% einstelbar zu machen? Wenn Regelung: ein langsamer 
I-Regler sollte reichen...

von Sebastian (Gast)


Lesenswert?

Kann mir einer sagen wie ich am besten jetzt die Signale von Lüfter 
auswerten kann?Es kommen ja pro Umdrehung 2 Signale also muss ich 
schonmal auf jeden fall durch 2 teilen.Aber wie rechnet man am besten 
die Umdrehung pro Minute aus weil eine Minute will ich ja nicht warten

von Joachim B. (jojo84)


Lesenswert?

Also das ist ja nun mal alles andere als schwierig! Du kennst doch einen 
Dreisatz, oder? Du mußt doch einfach nur einen Timer laufen lassen. 
Durch die Prozessorfrequenz weißt du doch, wie lange der Timer braucht, 
um um 1 erhöht zu werden.
Also, Zeit zwischen den Impulsen stoppen und einfach auf die Minute 
hochrechnen! Arbeite dich mal hier durch:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR
und hier:
http://www.mikrocontroller.net/articles/Festkommaarithmetik

Gruß

von Sebastian (Gast)


Lesenswert?

Also ich habe den Lüfter mit den 3 Kabeln der gibt alle 180° ein Signal.
Natürlich könnte ich den Lüfter auch einfach von 0-100% einstellen das 
würde auch funktionieren,aber ich möchte ja mit meinen Projekten 
dazulernen.Ich Programmiere ja mit Bascom,weil es relativ leicht ist mit 
den Bascom Funktionen schnelle Ergebnisse zu bekommen.Wenn mein Programm 
dann läuft schreib ich es komplett um (Rufe alle Register usw. manuell 
auf).Ich möchte irgendwann wenn ich Bascom behersche auf C umsteigen.Ich 
habe auch ganz wenig C Kenntnisse weil ich damit angefangen habe,aber 
ich fand es für den Einstieg zu schwer.Ich mache das ganze noch nicht so 
lange.Und bis jetzt kann ich nur die Grundfunktionen.Ich werde mich mal 
durch die Links lesen und das wird mir bestimmt weiter helfen.Also wie 
ich einen Transistor anschließe ist mir schon bekannt, da ich aber nicht 
soviel Ahnung von Elektronik habe dachte ich eigentlich das ein 
Transistor einfach nur die 12V durchleiten kann.Das dieser auch den 
Strom regeln kann ist mir neu (außer irgendwelche IC's).Dreisatz ist mir 
noch bekannt:)
Also werde mich dann jetzt ans lesen machen.Sollten danach noch immer 
Fragen offen sein,darf ich mich bestimmt ja nochmal melden oder??

von Sebastian (Gast)


Lesenswert?

Also ich habe mich jetzt mal ein wenig da durchgelesen und wollte mal 
fragen ob ich das jetzt richtig gerechnet habe.

Aufgabe möchte 1 Sek. errechnen.

Also Takt 8Mhz/Prescaler (1024)= 781,25Khz

1/781,25=128us
1/128 =7812,5 Zählerschritte

Timer1 16bit =65535

65535-7812,5= 57722,5 ab/aufrunden = 57723

Dann den Timer1 mit TCNT1=57723 vorladen.

Ist das so richtig?

von Joachim B. (jojo84)


Lesenswert?

Jo, ich glaub das passt so. Aber das find ich sehr umständlich. Da hat 
ja jeder seinen eigenen Geschmack, aber ich würd es anders lösen.
Es gibt ja grundsätzlich zwei Lösungsansätze, um auf deinen 
Drehzahl/Frequenz zu kommen.
1. eine definierte Zeit warten und Pulse zählen. Vorteil: du hast direkt 
die Drehzahl/Zeiteinheit vorliegen. Nachteil: du mußt immer deine 
Zeiteinheit abwarten.
2. du stoppst die Zeit, zwischen zwei Pulsen. Klarer Vorteil: du mußt 
nicht immer erst deinen Messzeitraum von 1. abwarten, sondern kannst mit 
jedem neuen Puls die Drehzahl errechnen. Das ist auch der "Nachteil": 
Mit der gestoppten Zeit mußt du das ganze dann auf die genaue 
Drehzahl/Zeiteinheit umrechnen. Das sollte aber kein Problem sein (hoff 
ich).

Der Timer1 kann im CTC-Mode betrieben werden, der ist hier dein Freund. 
Dann sparst du dir das Vorladen :) .

Und ich würd mir eine "einfachere" Zeiteinteilung einfallen lassen. Wenn 
du z.B. bei 8MHz den Vorteiler 8 benutzt weißt du ja schon, daß er alle 
1 µs +1 macht. Da kommst du dann aber sehr schnell auf sehr große 
Zahlenwerte (bei niedrigen Drehzahlen). Jetzt stell dir mal vor, daß 
dein Timer immer bei 250 überläuft. Ein Interrupt tritt also alls 250 µs 
oder alls 0,25 ms auf. Jetzt Zähl doch einfach mal die Interrupts 
zwischen zwei Pulsen. Durch die geschicke Zeiteinteilung sind die Werte 
dann auch leichter zu verstehen. Jetzt hast du z.B. 234 Interrupts 
zwischen den Pulsen. Also sind 234 * 0,25 ms vergangen, alse 58,5 ms. 
Und so oft, wie die Zahl jetzt in 1s reinpasst, daß ist deine 
Drehzahl/Sekunde :) .
Klar soweit?!

Übrigens:
http://www.google.de/search?hl=de&safe=off&client=firefox-a&hs=eXT&rls=org.mozilla:de:official&q=danke+sagen&revid=401858695&sa=X&ei=q_MyTduWJdCOswaTrOT4CQ&ved=0CCUQ4QIoAQ

Gruß

von Sebastian (Gast)


Lesenswert?

Also so einiger maßen verstehe ich das schon aber nicht so richtig.

Ich würde schon die Variante bevorzugen die Zeit zu stoppen zwischen den 
2 Impulsen.

Aber wär vielleicht jemand so nett mir das genauer zu erklären.Ich steh 
irgendwie total auf dem Schlauch.

MfG Basti

von Sebastian (Gast)


Lesenswert?

Würde es eventuell auch so gehen?

Wenn ich den Timer auf Prescale 8 stelle würde ja bei 8Mhz der Takt 1us 
sein.Dann in der Routine den Timer auf 0 stellen Und anfangen zu zählen 
dann im Programm die Variable Zahlstand aufrufen und umrechnen auf eine 
Minute


'Timer1----------------------------------------------------------------- 
-----------
Config Timer1 = Counter , Prescale = 8 , Edge = Falling
On Timer1
Enable Timer1
Start Timer1


Timerroutine:
Timer1 = 0
Zahlstand = Timer1

von Joachim B. (jojo84)


Lesenswert?

Also ehrich, ich hab dir die Formel doch schon auf dem Silbertablett 
serviert!

Annahme:
Controller läuft bei 8 MHz, Vorteiler des Timers 8(NUR BEISPIEL, weil 
einfach zu rechnen!) Über das Format der Zahlen mußt du dir selbst 
Gedanken machen...
-> Timer zählt mit 1 MHz (1 µs pro Zählschritt). Erstes Signal kommt, 
Timer starten. Timer-Vergleichswert bei 249 -> 250 Zählschritte bis 
ISR-Aufruf (bitte korrigieren falls falsch). Es dauert also 250 * 1 µs (
In der ISR zählst du jetzt in einer Variablen die Aufrufe des 
Interrupts.
Jetzt kommt irgendwann das nächste Signal -> Timer stoppen.
Jetzt steht in der Variablen z.B. 234 drin. 234 mal sind also 250 µs 
verstrichen -> 234 * 250 = 58500 µs = 58,5 ms. Jetzt steht aber ja noch 
ein Rest im Timer. Der hat ja immer hochgezählt. Auch wenn er keinen 
Interrupt ausgelöst hat, dann beinhaltet er aber ja noch einen Zählwert, 
bei dem dann durch das zweite Signal gestoppt wurde.
Der Restwert sei 120. Durch unseren Vorteiler wissen wir, daß dieser 
Wert direkt eine Zeit in µs repräsentiert. Diesen Wert mit 
berücksichtigen:
58500 + 120 = 58620 µs = 58,62 ms.
Und jetzt: siehe oben!!! Wie kriegt man raus, wie oft eine Zahl, in eine 
Andere reinpasst? Division!
Denkweise: für eine Umdrehung brauch das Ding 58,62 ms (oder auch 
0,05862 s). Das heißt ich schaffe in 1s... ähm... 1 / 0,05862 = 17,06 
Umdrehungen!
Pro Minute sind das also... ähm... 17,06 * 60 = 1023,5 Umdrehungen! Und 
wenn wir berücksichtigen, daß pro Umdrehung 2 Signale kommen teilen wir 
nochmal durch 2 und sind dann bei  511,77.
Das ist doch echt mal kein Stoff aus dem Mathe-LK :) .

http://www.google.de/search?q=danke+sagen&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:de:official&client=firefox-a

Gruß

von Sebastian (Gast)


Lesenswert?

Nur eine Frage habe ich noch wie Lese ich die Werte jetzt am besten ein?
Das ist eigentlich mein einziges Problem den rest verstehe ich.


MfG Sebastian

Und PS vielen dank für die Hilfe

von Joachim B. (jojo84)


Lesenswert?

Konkretisiere deine Fragen bitte. Mit der Frage

> wie Lese ich die Werte jetzt am besten ein?

kann keiner was anfangen. Wie ein Signal (ich vermute, daß du das 
meinst) eingelesen werden muß hängt nur davon ab, wie das Signal 
aussieht. Wenn du nicht weißt, was du messen willst brauchst du gar 
nicht erst mit dem Messen anzufangen. Zu fast allen Hardware-Fragen im 
Bezug darauf, wie ein Signal auszusehen hat, gibt das Datenblatt 
Auskunft.
Die Zauberformel hier im Forum lautet fast immer "Konkrete Frage, 
konkrete Antwort", und Eigeninitiative. Ist nicht bös gemeint, aber 
versuch nochmal selbst dahinter zu kommen...

Gruß

von Sebastian (Gast)


Lesenswert?

Ich habe jetzt noch eine Lösung gefunden.Womit ich aber Probleme habe 
ist zu wissen wo das Programm wieviel Zeit braucht.Klar mit dem Timer 
ist mir das klar.Aber wenn ich jetzt z.B. den Timer overflow auf 1us 
stelle.Dann aber die Werte z.B. mit ICP oder Int auslese haben ja die 
eine eigende Routine und mit meiner Timer Routine nichts zu tun.Und da 
bin ich am verzweifeln.Woher weiß ich jetzt wann der Interrupt 
auftritt?Ich habe darüber auch nicht wirklich was in meinem Buch stehen 
oder irgendwo eine vernünftige erklärung gefunden.Was ich auch nicht 
wirklich verstehe ist wenn ich den Timer wieder auf 1us stelle und dann 
den Timer auf 0 setze Timer starte Wert auslese und Timer wieder stoppe 
dann mißt doch der Timer garnicht mehr genau auf 1us,oder nicht?

Na ja mein Code sieht jetzt auf jeden fall so aus,das einzige was jetzt 
noch nicht gemacht ist,ist die Umrechnung auf RPM/min.

$regfile = "m8def.dat"
$crystal = 8000000

Declare Function Lopulse() As Word
Dim Value As Word
Config Lcd = 16 * 2
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , 
Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Cursor Of

Config Pinb.0 = Input
Set Portb.0.0
Inputpin Alias Pinb.0

Config Timer1 = Timer , Prescale = 8,

On Timer1 Overflow_isr Nosave

Enable Timer1
Enable Interrupts

Do
Value = Lopulse()
Cls
Locate 1 , 1
Lcd Value ; "Wert"
Waitms 20
Loop

End

Function Lopulse() As Word
While Inputpin <> 0 : Wend
Tcnt1 = 0
Start Timer1
While Inputpin = 0 : Wend
Stop Timer1
Lopulse = Tcnt1
End Function Lopulse()

Overflow_isr:
!push r24
Stop Timer1
Tcnt1 = 0
!pop r24
Return

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Ich habe jetzt noch eine Lösung gefunden.Womit ich aber Probleme habe
> ist zu wissen wo das Programm wieviel Zeit braucht.

Im Idealfall brauchst du das gar nicht wissen.

> Klar mit dem Timer
> ist mir das klar.

Na dann passt es doch.
Das ist die einzige Zeit, die du wirklich wissen musst.

> Aber wenn ich jetzt z.B. den Timer overflow auf 1us
> stelle.Dann aber die Werte z.B. mit ICP oder Int auslese haben ja die
> eine eigende Routine und mit meiner Timer Routine nichts zu tun.

Macht ja nichts.

> Und da
> bin ich am verzweifeln.Woher weiß ich jetzt wann der Interrupt
> auftritt?

Musst du nicht wissen. Genau dazu gibt es den Interrupt Capture. Der 
erledigt das wegspeichern des Timer-Wertes in Hardware. Du brauchst dir 
nur noch die Zählerwerte von der Capture Einheit zu holen. Bei denen 
hast du die Gewissheit, dass sich genau im Moment des Pulses 
weggespeichert wurden. Selbst wenn du dir diese Ergebnis in paar µs 
später abholst.

> Ich habe darüber auch nicht wirklich was in meinem Buch stehen
> oder irgendwo eine vernünftige erklärung gefunden.Was ich auch nicht
> wirklich verstehe ist wenn ich den Timer wieder auf 1us stelle und dann
> den Timer auf 0 setze

Im Idealfall lässt du den Timer durchlaufen.

Stell es dir wie eine Uhr vor:
Dein Kumpel schreit 'Jetzt'. Du schaust auf deine Uhr und siehst, dass 
der Sekundenzeiger auf 18 steht. Das merkst du dir.
Nach einer gewissen Zeit schreit den Kumpel wieder 'Jetzt'.
Blick auf die Uhr: Der Sekundenzeiger steht auf 42.
Wieviele Sekunden sind also zwischen den beiden 'Jetzt' vergangen?
42 - 18 = 24

Zu keinem Zeitpunkt musstest du die Uhr anhalten oder auf 0 stellen und 
trotzdem hast du die Information die du willst.
Das einzige worauf du aufpassen musst, ist wenn der Sekundenzeiger 1 
oder mehrere male über die 60 drüberkommt. Dann musst du dein Ergebnis 
entsprechend korrigieren. Ist aber nicht wirklich schwer.

> Timer starte Wert auslese und Timer wieder stoppe
> dann mißt doch der Timer garnicht mehr genau auf 1us,oder nicht?

Und wozu brauchst du so eine Genauigkeit?
Bei einem Rührermotor?


Meiner Meinung nach werden viel zu viele Probleme damit angegeangen, 
dass Timer unnötigerweise auf viel zu tiefer Ebene vorgeladen, 
0-gesetzt, gestartet-gestoppt oder händisch ausgelesen werden. Alles 
Dinge, die man beim Einsatz der eingebauten Hardware und dafür lesen des 
Datenblatts und benutzen der kleinen grauen Zellen gar nicht braucht.

von Sebastian (Gast)


Lesenswert?

Also würdest Du einfach den Timer einstellen als timer und laufen lassen
dann eine Interroupt Routine Int0 schreiben wo dann drin steht

startwert=timer1
Hi low flanke abwarten
endwert=timer1
startwert-entwert=value
value*?=rpmmin (das dann im Hauptprogramm)
return

Richtig?

MfG Sebastian

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Also würdest Du einfach den Timer einstellen als timer und laufen lassen
> dann eine Interroupt Routine Int0 schreiben wo dann drin steht
>
> startwert=timer1
> Hi low flanke abwarten

nein

In dem Moment, in dem du in einer Interrupt Routine das Wörtchen 
'warten' gebrauchst (ausser bei wirklich kleinen Zeiten, aber den Fall 
hast du nicht), bist du schon auf dem Holzweg.

Du kriegst doch 2 Interrupts hintereinander, für jede halbe Umdrehung 
einen. In jedem Interrupt brauchst du nur nachsehen, wie sich der 
jetzige Timerwert in Bezug auf den Timerwert im letzten Interrupt 
verhält.

Drum hat auch in meinem Realwert-Beispiel dein Kumpel "jetzt" gerufen. 
Ich hab da nicht geschrieben, dass du ab dem ersten Ruf an seinen Lippen 
klebst und nur auf den 2.ten Ruf wartest. Kumpel ruft und du siehst auf 
die Uhr. Das ist das Pendant zum Interrupt Aufruf mit Timer auslesen.

Und ja. Es gibt Variablen, in denen man sich Werte solange aufheben 
kann, bis man sie dann tatsächlich braucht.

von Sebastian (Gast)


Lesenswert?

Ah ich glaube ich hab es verstanden.Da Int0 ja bei jeden feststellen 
einer Änderung am Pin ins Unterprogramm geht brauche ich ja garnicht auf 
ein Signal warten sondern nur den Timerwert speichern.Diesen dann als 
sagen wir mal wertneu und wertalt speichern und vergleichen.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Ah ich glaube ich hab es verstanden.Da Int0 ja bei jeden feststellen
> einer Änderung am Pin ins Unterprogramm geht brauche ich ja garnicht auf
> ein Signal warten sondern nur den Timerwert speichern.Diesen dann als
> sagen wir mal wertneu und wertalt speichern und vergleichen.

Im Prinzip.
Und wenn du jetzt noch die Forderung mit dazu nimmst, dass das Auslesen 
des Timers möglichst zeitnah mit dem tatsächlichen Auftreten des Signals 
passieren soll und daher von der Hardware gemacht werden soll, dann hast 
du den Input Capture Interrupt des Timers entdeckt.

Anstelle das du dir einen Int0 auslösen lässt und selbst danach 
irgendwann den Timer ausliest, erledigt die Hardware beides in einem 
Aufwasch: Die Signaländerung wird detektiert UND gleichzeitig wird der 
aktuelle Timerwert in Hardware weggespeichert UND ein entsprechender 
Interrupt wird generiert.

Und weil das so ist, braucht man die tatsächliche Programm-Laufzeit vom 
Auftreten des Signals bis dann der Timer in der ISR ausgewertet wird, 
gar nicht mehr wissen.

Allerdings muss man auch sagen, dass die Programmlaufzeit vom Auftreten 
des Signals bis du dann den Timer ausliest im Grunde uninteressant ist. 
Deine Forderung nach 1µs braucht nämlich kein Mensch. Damit könntest du 
die Drehzahl auf 1 Millionstel Umdrehungen PRO SEKUNDE feststellen. Ich 
bezweifle, dass dein Rührwerk überhaupt so gleichmässig dreht, dass das 
Sinn macht. Wenn überhaupt, wird sich bei dir das meiste im 
Millisekundenbereich abspielen. Und 1 Millisekunde ist für einen µC eine 
laaaange Zeit.

von Sebastian (Gast)


Lesenswert?

Kannst Du mir noch vielleicht sagen in welchen register start endwert 
gespeichert wird.Dann hätte ich alles was ich brauche.

Vielen dank für deine hilfe

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Kannst Du mir noch vielleicht sagen in welchen register start endwert
> gespeichert wird.Dann hätte ich alles was ich brauche.

Sei mir nicht böse.
Aber das wichtigste was du brauchst, ist das Datenblatt zu deinem 
Prozessor. Denn da steht das alles drinnen.

Und deswegen möchte ich die Frage hier nicht beantworten. Denn der 
Glaube: Ich brauch das Datenblatt nicht, weil ich eh in BASCOM arbeite 
... das ist ein Irrglaube.

von Sebastian (Gast)


Lesenswert?

Kein Problem bin dir nicht böse.Ich habe es jetzt so gelöst

Oncapture:
Wcapture = Capure1
Wzaehler = Wcapture - wcapturealt
Wcapturealt = Wcapture
Return

von Sebastian (Gast)


Lesenswert?

So habe es jetzt nochmal geändert mein ganzes Programm sieht bis jetzt 
so aus.Jetzt muss ich noch ein PWM Signal erzeugen für den Motor und 
natürlich den Sensor für die Temperatur einfügen.Außerdem noch die 
Umrechnung in die Drehzahl.PWM kann ja mit timer1 und 2 erzeugt werden 
könnte ich jetzt noch diese mit timer1 machen oder ist es sinnvoll 
timer2 zu benutzen.


$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600
Dim 1count As Long At &H60
Dim Wcountlo As Word At &H60 Overlay
Dim wcounthi as word at &h62 overlay
Dim Grad As Word
Dim Rpm As Word


On Icp1 Oncapture
On Ovf1 Onoverflow

'Display 
Einstellungen----------------------------------------------------------- 
-------------------------------
Config Lcd = 16 * 2
Config Lcdbus = 4
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , 
Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Cursor Off

'ports 
einstellungen----------------------------------------------------------- 
---------------------------------
Config Portb.1 = Output                                     'Test Output 
Motor
Config Portc.0 = Input                                      'ADC0 Input
Config Portc.1 = Input                                      'ADC1 Input
Config Portb.3 = Output                                     'Outpu 
Relais Wärmeplatte
Config Portb.0 = Input
Portb.0 = 1

'Timer1----------------------------------------------------------------- 
---------------------------------------
Config Timer1 = Timer , Prescale = 1024 , Capture Edge = Falling , Noise 
Cancel = 1
Enable Timer1
Enable Icp1
Enable Interrupts


'ADC-------------------------------------------------------------------- 
---------------------------------------
Config Adc = Free , Prescaler = 4 , Reference = Internal
Start Adc


'----------------------------------------------------------------------- 
---------------------------------------

'Hauptprogramm

Do
Disable Interrupts
Cls
Locate 1 , 7                                                'Nur zum 
test
Lcd 1count ; "Wert"
wcounthi=0
Enable Interrupts
Grad = Getadc(0) / 6                                        'ADC0 
Einlesen
Locate 1 , 1
Lcd Grad ; "ß"
Rpm = Getadc(1)                                             'ADC1 
Einlesen
Locate 2 , 1
Lcd Rpm ; "Rpm"
Waitms 30
If Grad < 60 Then
Portb.3 = 1
Else
Portb.3 = 0
End If
Loop

'------------------------------------------------------------------
Oncapture:
Timer1 = Timer1 - capture1
Wcountlo = Capture1
Return

Onoverflow:
Incr Wcounthi
Return



MfG Sebastian

von Sebastian (Gast)


Lesenswert?

Habe da mal eine frage zum PWM.

Ich benutzte jetzt den Timer2 so eingestellt

Config Timer2 = Pwm , Prescale = 8 , Compare Pwm = Clear Up , Pwm = On
Enable Timer2
Start Timer2

im Programm habe ich dann

Motorpwm = Rpm / 4
Ocr2 = Motorpwm

Jetzt habe ich aber das Problem das wenn ich ungefähr bei einen Drittel 
bin (Poti) das der Strom wieder fällt dann aber wieder ansteigt.Woran 
kann das liegen?

von Sebastian (Gast)


Lesenswert?

Kann mir jemand sagen wie ich 0,000128 in eine VARIABLE kriege?

Weil ich rechne jetzt

1x Umdrehung = Takte Timer*0.000128s >(dauert ein Takt)
UmdrehungMin.= Minute(60)/Umdrehung

ist doch richtig so oder?

von Karl H. (kbuchegg)


Lesenswert?

Sebastian schrieb:
> Kann mir jemand sagen wie ich 0,000128 in eine VARIABLE kriege?

Wenn es irgendwie geht, willst du das gar nicht.

Man kann zb mit 0.75 multiplizieren, indem man zuerst mit 3 multiplizert 
und dann durch 4 dividiert. Man muss nur aufpassen, dass kein 
Zwischenergebnis entsteht, welches für den Datentyp zu gross ist.

> Weil ich rechne jetzt
>
> 1x Umdrehung = Takte Timer*0.000128s >(dauert ein Takt)
> UmdrehungMin.= Minute(60)/Umdrehung

Forme die Umrechnung um. Das kann man auch anders berechnen.

von Joachim B. (jojo84)


Lesenswert?

Moin,

darum hab ich oben weiter (glaub ich) auch schon auf den Artikel zur 
Festkommaarithmetik verwiesen.
Du kriegst die Zahl 0,000128 nicht SO in eine Variable, die für den 
Controller angenehm zu verarbeiten ist.
ABER: wer schreibt dir denn vor, daß du in "Sekunden" rechnen mußt? Wenn 
du alles z.B. in Microsekunden rechnest hast du auf einmal 128 da stehen 
:) . Kein Komma, nur die Tatsache, daß eine Sekunde aus 1000000 µs 
besteht.
Mit einem ähnlichen beispiel steht es hier auch irgendwo, wie man eine 
eingelesene Spannung am ADC in einen Wert in Volt umwandelt. Du rechnest 
einfach in Millivolt, und schon verschwinden die Kommas.
Und für die Ausgabe: kein Problem! Dann machst du (bei den Millivolt) 
erst "durch 1000", dann kommt z.B. "3" heraus, dann gibst du ein Komma 
aus (einfach so) und dann gibst du deine "Millivolts % 1000" aus.

Alles wird gut...

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.