Seit gegrüßt liebes Forum
In der Schule haben wir zurzeit nen Projekt am laufen und ich soll die
Lüftersteuerung programmieren
Hardware ist nen ATMEGA32 und nen ganz normaler 5V Lüfter
Ich hab von mein Lehrer folgende Quelltexte bekommen mit denn ich das
programmieren könnte.
Nu komm ich da nicht ganz mit da wir davor nur LEDs zum leuchten
gebracht haben ^^
Kann mir irgendwer bissel helfen dabei?
mfg Christian
#include <avr/io.h>
#define F_CPU 8000000UL // 1 MHz
#include <util/delay.h>
1.)
int main(void)
{
DDRB |= _BV(PB3);
TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));
TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10bit-Counter, nicht
invert. PWM
TCCR1B = (1<<CS10); // Pre-Scaler = 1, also ohne Teiler
int i=255;
while(1)
{
while(i>100){
OCR0 = i;
_delay_ms(10);
i--;
}
while(i<255){
OCR0 = i;
_delay_ms(10);
i++;
}}
return 0;
}
for (i=0;i<255;i=i+1)
OCR0=i;
_delay_loop_2(20000);}}
-----------------------------------------------------------------
2.)
#include <avr/io.h>
#define F_CPU 8000000UL // 1 MHz
#include <util/delay.h>
int main (void)
{
DDRB=0xff;
PORTB=0x00;
int i;
TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));
while(1)
{if (i=254) break;
for (i==0;i<254;i=i+1)
{OCR0=i;
_delay_loop_2(20000);
}}
}
----------------------------------------------------------------------
3.)
#include <avr/io.h>
#define F_CPU 8000000UL // 8 MHz
#include <util/delay.h>
int main(void)
{
int i;
DDRC |= _BV(PC1);
while(1){
//LED aus
PORTC |=_BV(PC1);
for(i=0;i<100;i++) {
_delay_ms(20);
}
//LED leuchtet schwach
for(i=0;i<100;i++){
PORTC &= ~_BV(PC1); _delay_ms(1);
PORTC |=_BV(PC1); _delay_ms(19);
}
//LED leuchtet etwa halbhell
for(i=0;i<100;i++){
PORTC &= ~_BV(PC1); _delay_ms(5);
PORTC |=_BV(PC1); _delay_ms(15);
}
//LED leuchtet hell
for(i=0;i<100;i++){
PORTC &= ~_BV(PC1); _delay_ms(19);
PORTC |=_BV(PC1); _delay_ms(1);
}
}
return 0;
}
Was genau ist eine "Lüftersteuerung"? Was soll die Schaltung machen? PWM
ist sicherlich ein gutes Stichwort. In den Codes vom Lehrer sind mir
irgendwie zu viele delays...
fR4NkY schrieb:> In der Schule haben wir zurzeit nen Projekt am laufen und ich soll die> Lüftersteuerung programmieren
Und wie sehen die Rahmenbedingungen aus? Was genau wird gefordert?
Ich soll z.B. den Lüfter Drosseln können bzw. sich schneller Drehen
lassen können und wenn mein Klassenkamerad sein Projekt fertig hat soll
es mit den Temperaturen automatisch steuerbar sein
troll schrieb:> Was genau ist eine "Lüftersteuerung"? Was soll die Schaltung machen? PWM> ist sicherlich ein gutes Stichwort. In den Codes vom Lehrer sind mir> irgendwie zu viele delays...
nur im letzten. Aber der ist prinzipiell sowieso ungeeignet und taugt
eigentlich nur dazu sich klar zu machen, was eine PWM ist.
In den restlichen Beispielen sind die delays nur deswegen in der main
Schleife, damit sich der OCR Wert nicht zu schnell verändert und man an
der LED auch sieht, dass sich was verändert. Würde ich auch so machen,
da es
a) für die PWM Funktionalität nicht wichtig ist
b) auch für Anfänger einfach zu durchschauen ist (na ja. sein sollte.
Siehe TO)
fR4NkY schrieb:> Ich denk mir das so....
Jetzt muss man sich nur noch eine Aufgabenstellung ausdenken, die zum
Programm passt. Allerdings wird das schwierig, denn das was du da
geschrieben hast, ist ganz großer Unsinn.
fR4NkY schrieb:> Seit gegrüßt liebes Forum> In der Schule haben wir zurzeit nen Projekt am laufen und ich soll die> Lüftersteuerung programmieren>> Hardware ist nen ATMEGA32 und nen ganz normaler 5V Lüfter
Hmm, na da braucht man aber noch extra-Hardware, der wird direkt von
einem Pin eines µC wohl nicht laufen. Ausser es ist einer mit
PWM-Steuerung, die kenne ich aber nur mit 12V Betriebsspannung und extra
5V-PWM-Pin für PC-Kühlung.
> Ich hab von mein Lehrer folgende Quelltexte bekommen mit denn ich das> programmieren könnte.> Nu komm ich da nicht ganz mit da wir davor nur LEDs zum leuchten> gebracht haben ^^> Kann mir irgendwer bissel helfen dabei?>> mfg Christian>> #include <avr/io.h>> #define F_CPU 8000000UL // 1 MHz
Gelogen. Das sagt 8MHz, nicht 1MHz. Sollte die delays kaputtmachen...
> #include <util/delay.h>>> 1.)> int main(void)> {> DDRB |= _BV(PB3);> TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));> TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1); // 10bit-Counter, nicht> invert. PWM> TCCR1B = (1<<CS10); // Pre-Scaler = 1, also ohne Teiler>> int i=255;>> while(1)> {>> while(i>100){> OCR0 = i;> _delay_ms(10);> i--;> }
Hier wird i alle 10ms von 255 heruntergezählt (bis 100) und in OCR0
geschrieben. Ich habs nicht nachgesehen, aber macht wohl eine abnehmend
breite PWM an einem Pin.
> while(i<255){> OCR0 = i;> _delay_ms(10);> i++;> }}
Alle 10ms wieder bis 255 hochzählen, s.o.
> return 0;> }
Der Code oben ist mis-formatiert... Die schliessende Klammer hier ist
das Ende von main().
> for (i=0;i<255;i=i+1)> OCR0=i;> _delay_loop_2(20000);}}
Wenn ich mich nicht verguckt habe wird das nie ausgeführt, ist also
Code-Müll.
Das compiliert dann nichtmal.
> -----------------------------------------------------------------> 2.)> #include <avr/io.h>> #define F_CPU 8000000UL // 1 MHz
s.o.
> #include <util/delay.h>>>> int main (void)> {> DDRB=0xff;> PORTB=0x00;> int i;
i ist nicht initialisiert. So wird das nix.
> TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));> while(1)> {if (i=254) break;> for (i==0;i<254;i=i+1)
"i==0"? Hehehehe, ich glaube nicht... ;-)
> {OCR0=i;> _delay_loop_2(20000);> }}> }
Naja, sollte wohl i einmal von 0 bis 254 hochzählen und jeweils in OCR0
schreiben. s.o.
> ----------------------------------------------------------------------> 3.)> #include <avr/io.h>>> #define F_CPU 8000000UL // 8 MHz
Sieh an, es ist mal richtig.
> #include <util/delay.h>>>> int main(void)> {> int i;>> DDRC |= _BV(PC1);>>> while(1){>> //LED aus> PORTC |=_BV(PC1);> for(i=0;i<100;i++) {> _delay_ms(20);> }
2 Sekunden LED aus (die Blöcke unten dauern auch je 2s).
> //LED leuchtet schwach> for(i=0;i<100;i++){> PORTC &= ~_BV(PC1); _delay_ms(1);> PORTC |=_BV(PC1); _delay_ms(19);>> }LED jeweils 1ms an, 19ms aus -> leuchtet schwach.
> //LED leuchtet etwa halbhell> for(i=0;i<100;i++){> PORTC &= ~_BV(PC1); _delay_ms(5);> PORTC |=_BV(PC1); _delay_ms(15);>> }LED jeweils 5ms an, 15ms aus -> leuchtet heller.
> //LED leuchtet hell> for(i=0;i<100;i++){> PORTC &= ~_BV(PC1); _delay_ms(19);> PORTC |=_BV(PC1); _delay_ms(1);> }>> }LED jeweils 19ms an, 1ms aus -> leuchtet hell.
>> return 0;
Das ist nur Formalität für den Compiler...
> }
Dieser letzte Code sieht wie der einzige aus der wirklich direkt
funktionieren könnte. Was der macht nennt sich Soft-PWM.
Um zu verstehen wie Du den Lüfter ansteuern kannst solltest Du Dich mit
PWM (in Hardware) - was die ersten zwei Schnipsel versuchen zu tun - und
Soft-PWM - was der letzte Schnipsel tut - befassen. Dazu sollte es genug
zu lesen geben.
Kleiner Tipp von mir:
Wenn du deine 3 Source Code Files einfach nur als Attachment anhängst,
und nicht sinnloser weise mit dem ganzen restlichen Krempel in ein
RAR-File packst, dann sehen sich das auch deutlich mehr Forumsteilnehmer
an.
Das ist jetzt aber nicht dein Ernst, oder?
Hat dir schon mal wer gesagt, dass ein Computer auch rechnen kann?
Deine Temperaturausgaben, deine OCR Berechnung ... die stinken förmlich
20 Meter gegen den Wind danach, dass es da einfache Formeln gibt.
Benennung wichtiger Variablen - ausserst mies.
Dass eine Variable y mit den Werten 0 und 1 anzeigt, ob <irgendwas> im
'Automatik-Modus' oder im 'Manuell-Modus' läuft, das muss man sich auch
erst mal aus dem Code erlesen.
Alles in allem ist der Code für die gezeigte Funktionalität deutlich zu
kompliziert.
Daraus (aber nicht nur daraus) resultiert eine Unübersichtlichkeit, die
nicht gerade hilfreich bei der Beurteilung des Codes ist.
Was die Variable x in dem Code macht, hab ich noch nicht rausgefunden.
Hat die überhaupt irgendeine Funktion, ausser dass sie offenbar
irgendwie durch Taster beeinflusst wird?
Wenn du mich fragst, wie ich das als Lehrer beurteilen würde.
Schwach. Sogar ziemlich schwach.
Wenns läuft, könntest du bei mir gerade noch so die Kurve kratzen, wenn
ich dein Lehrer in einem Fach wäre, indem es um Programmieren geht.
Also die Bedienphilosophie aus dem Code zu erkennen - damit tu ich mich
echt schwer. Zwischen i und x scheint es da einen Zusammenhang zu geben.
Aber mir erschliesst sich nicht, welcher das sinnvollerweise sein
könnte.
Dazu kommt, dass ich als Benutzer auf dem LCD auch nicht sehen kann, mit
welcher Einstellung das Programm momentan den Lüfter ansteuert, bzw. was
mein Tastendruck gerade bewirkt hat.
Was ist los?
Hat es dir die Sprache verschlagen?
Du wolltest doch eine ehrliche Meinung, oder nicht?
Es hat ja auch keinen Sinn, wenn ich hier auf Friede, Freude, Eierkuchen
mache.
Hallo erst mal.
Ich bin einer von denen der daran arbeiten.
Zur Verteidigung wir wurden mit diesen Thema ins kalte Wasser
geschmissen wir hatten vor einer Woche nicht mal eine Ahnung was die PWM
ist und wie sie überhaupt funktioniert.
Na klar ist das alles ziemlich undurchschaubar, aber das ganze ist für
uns einen neues Gebiet und besteht nur durch ausprobieren und testen.
Klar gibt es bessere Lösungen dazu, aber zu uns wurde gesagt wir sollen
erst mal die Stufenvariante machen.
Das mit den LCD teil und die Temperatur Erkennung kommt nicht von uns
und sind noch am versuchen wie wir das ganze zusammen zum arbeiten
kriegen.
Das mit den
while(bit_is_clear(PIND,0)){_delay_ms(1000);}
while(bit_is_clear(PIND,1)){_delay_ms(1000);}
while(bit_is_clear(PIND,2)){_delay_ms(1000);}
wurde genutzt, da der Lehrer zu uns meinte wir brauchen das für das
entprellen der Tasten.
Die Variable i sollte per Tasten druck um eins erhöht bzw. verringert
werden.
x war für die Verrieglung gedacht und y für die Umstellung in
Automatisch und Manuelle Einstellung.
Ich bin kein Profi in C und bewege mich am Anfang des Mikrocontroller.
Für bessere eine Lösungen bin ich immer offen und man lernt immerhin was
dazu.
Karl Heinz Buchegger schrieb:> Was ist los?> Hat es dir die Sprache verschlagen?
Karl Heinz in Höchstform. :-)
Warte mal bis morgen, dann hat der TO Zeit deine ganzen Kommentare zu
verdauen und nachzubessern.
troll schrieb:> Karl Heinz Buchegger schrieb:>> Was ist los?>> Hat es dir die Sprache verschlagen?> Karl Heinz in Höchstform. :-)> Warte mal bis morgen, dann hat der TO Zeit deine ganzen Kommentare zu> verdauen und nachzubessern.
Das ist auch dringend notwendig, da nachzubessern.
So, und jetzt les ich mal die Antwort vom TO
Patrick (Gast) schrieb:> Hallo erst mal.>> Ich bin einer von denen der daran arbeiten.>> Zur Verteidigung wir wurden mit diesen Thema ins kalte Wasser> geschmissen wir hatten vor einer Woche nicht mal eine Ahnung was die PWM> ist und wie sie überhaupt funktioniert.
Wenn du aufmerksam die Kommentare gelesen hast, dann kommt da die
eigentliche PWM gar nicht vor.
> Na klar ist das alles ziemlich undurchschaubar, aber das ganze ist für> uns einen neues Gebiet und besteht nur durch ausprobieren und testen.
Dann solltet ihr euren Code vorher durchsehen, ehe ihr ihn der Kritik
stellt.
Sowas
1
if((y==1)&&(i==1))//Wenn y==1 und i==1 ist,dann
2
{
3
4
OCR0=45;
5
6
7
}
8
9
if((y==1)&&(i==2))
10
{
11
OCR0=30;
12
13
}
14
if((y==1)&&(i==3))
15
{
16
OCR0=20;
17
}
18
if((y==1)&&(i==4))
19
{
20
OCR0=10;
21
22
}
23
if((y==1)&&(i==5))
24
{
25
OCR0=0;
26
27
}
28
29
//Automatich
30
31
if((y==0)&&(t==1))
32
{
33
34
OCR0=45;
35
}
36
37
if((y==0)&&(t==2))
38
{
39
OCR0=35;
40
41
}
42
if((y==0)&&(t==3))
43
{
44
OCR0=25;
45
}
46
if((y==0)&&(t==4))
47
{
48
OCR0=20;
49
50
}
51
if((y==0)&&(t==5))
52
{
53
OCR0=15;
54
55
if((y==0)&&(t==6))
56
{
57
OCR0=10;
58
}
59
if((y==0)&&(t==7))
60
{
61
OCR0=0;
62
63
}
ist induskutabel, da wurde keine 2 Minuten nach einer Alternative
gesucht.
> Klar gibt es bessere Lösungen dazu, aber zu uns wurde gesagt wir sollen> erst mal die Stufenvariante machen.
Ist alles ok.
Meine Kritik richtet sich ja auch hauptsächlich auf formale Dinge in
eurem Code.
> Das mit den LCD teil und die Temperatur Erkennung kommt nicht von uns> und sind noch am versuchen wie wir das ganze zusammen zum arbeiten> kriegen.
Na komm.
Die Abstände zwischen den Stufen sind alle gleich. Da wird euch ja doch
wohl was einfallen, wie man aus dem ADC Wert direkt die anzuzeigende
Temperatur errechnen kann.
>> Das mit den> while(bit_is_clear(PIND,0)){_delay_ms(1000);}> while(bit_is_clear(PIND,1)){_delay_ms(1000);}> while(bit_is_clear(PIND,2)){_delay_ms(1000);}>> wurde genutzt, da der Lehrer zu uns meinte wir brauchen das für das> entprellen der Tasten.
mag sein, dass er das gesagt hat. Nur
a) ausserhalb der Hauptschleife bringt das herzlich wenig, weil der Code
nie ausgeführt wird. (würde man sehen, wenn man den Code sauber
einrückt)
b) was soll das für eine Entprellung sein, die einen Programmdurchlauf
um 3 Sekunden verzögert?
> Die Variable i sollte per Tasten druck um eins erhöht bzw. verringert> werden.
Schön. Jetzt bin ich so schlau wie zuvor.
Und was bedeutet i? Sind das die Äpfel an Baum vom letzten Herbst? Ist
das die Geldmenge, die ihr dem Forum für Hausaufgabenmachen zahlt? Ist
das die Helligkeit des LCD-Hintergrunds?
Also was?
Nein - i ist die vom Benutzer eingestellte Stufe der
Lüftergeschwindigkeit!
Dann nenn die Variable auch so, dass man das im Code lesen kann!
if( i == 4 )
if( userSpeed == 4 )
da kennt man sich doch gleich viel besser aus, was denn hier eigentlich
ausgwertet wird.
> x war für die Verrieglung gedacht und y für die Umstellung in> Automatisch und Manuelle Einstellung.
detto.
Gib den Variablen Namen, die ihre Funktion wiederspiegeln!
Ok
Das mit der Schleife hätte ich eigentlich selber drauf kommen müssen.
Das erklärt auch einiges was beim drücken des Tasters passiert ist
Die Variablen richtige Bezeichnungen zu geben stimmt auch.
Eine reine Faulheit von uns aus an der stelle.
Das i die Stufen anzeigen soll ist entfallen zu erwähnen.
Wir hatten versucht mit i und y es auf dem LCD zu wieder geben und zu
sehen ob er diese Werte erhöht bzw. verringert.
Das mit den ADC haben wir wie gesagt nicht gemacht, daran arbeitet eine
andere Gruppe die auch die Werte ausgerechnet haben.
Na klar werde ich mir das ganze selber mal an gucken, aber am diesen Tag
war ich zu Frieden das er überhaupt was gemacht hat.
Ich werde mir deine Kritik zu Herzen nehmen.
fR4NkY schrieb:> So habs fertig Programmiert mein Lehrer hats noch nicht kontrolliert> könnte ihr mir verbesserungs Vorschläge geben?
Natürlich, ganz einfach! Zum Beispiel so:
So, hab's fertig programmiert. Mein Lehrer hat's noch nicht
kontrolliert.
Könnt Ihr mir Verbesserungsvorschläge machen?
> In der Schule haben wir zurzeit nen Projekt am laufen...
und
> Hardware ist nen ATMEGA32 und nen ganz normaler 5V Lüfter
Und dieses nervtötend-schwachsinnige "nen" würde ich mir auch
schleunigst abgewöhnen! Das ist eigentlich nur etwas für Leute, die auf
der Baumschule vom Gärtner unterrichtet werden.
Es heißt entweder
"In der Schule haben wir zur Zeit ein Projekt am Laufen"
oder für die Maulfaulen zur Not auch
"'n Projekt am Laufen".
Und
"Hardware ist ein ATMEGA32 und ein ganz normaler 5V-Lüfter."
Allerdings kannst Du durchaus "nen 5V-Lüfter am Laufen haben", weil der
Akkusativ Singular eines Maskulinums wie "der Lüfter" eben "den Lüfter"
heißt.
Die unbestimmten Nominativ- und Akkusativ-Formen heißen dementsprechend
"ein Lüfter" und "einen Lüfter" oder kurz "'n Lüfter" und "'nen Lüfter".
Sprich Deinen Lehrer mal darauf an, auf daß er eine kleine Spezialstunde
einlegen möge. Dein Kumpel Patrick hat da erkennbar auch noch ein paar
kleine Defizite ("aber das ganze ist für uns einen neues Gebiet") - die
ganze Klasse könnte also wohl einige Extra-Deutschstunden gut vertragen!
Idealerweise malt Euch der Herr Lehrer einfach mal eine
Deklinationstabelle für die bestimmten und unbestimmten Artikel der 3
verschiedenen Wortgeschlechter (maskulinum-femininum-neutrum) an die
Tafel und Ihr pinselt die Sache dann andächtig in Euer Heft und schlaft
eine Nacht darüber - dann isches drin im Köpfle! Ist im späteren Leben
wirklich hilfreich und nützlich, ohne Schmarrn!
Wenn's der Lehrer nicht hinbringt, mache ich es ;-)
Die Sache mit der Groß- und Kleinschreibung und die Interpunktion könnte
man auch noch mal kurz durchkauen, falls der Lehrkörper dazu die Kraft
findet.
Ich schreibe das übrigens nicht, um Euch zu piesacken oder zu triezen
(neudeutsch: dissen), sondern als wohlgemeinte Anregung, denn Euer
Geschreibsel ohne Punkt und Komma ist streckenweise ziemlich anstrengend
für jeden Leser - und Ihr wollt doch, daß Eure Beiträge bzw. Fragen
gelesen werden, damit möglichst viele brauchbare Antworten kommen, oder?
So, und nun viel Glück mit der Steuerung, aber das werdet Ihr schon
packen, Ihr seid ja schon auf dem Weg!
Patrick (Gast) schrieb:> Das mit den ADC haben wir wie gesagt nicht gemacht, daran arbeitet eine> andere Gruppe die auch die Werte ausgerechnet haben.
Dann wirf ihnen den Code als nicht akzeptabel zurück!
Es gibt da einen ganz einfachen Zusammenhang, da brauch ich nur 2
Minuten mit dem Taschenrechner mit den Werten spielen, um zu sehen, dass
es ihn gibt
Das sind die ADC Werte und die Temperaturen die da rauskommen sollen
ADC Temperatur
-------------------------------
462 20
500 25
537 30
575 35
612 40
650 45
687 50
725 55
762 60
800 65
837 70
875 75
912 80
950 85
987 90
Das die Temperaturwerte immer um 5° ansteigen, ist schon mal ein Indziz
dafür, dass man sich die ADC Werte mal ansehen sollte.
Im einfachsten Fall vergleicht man einfach mal 2 aufeinanderfolgende
Werte
ADC Temperatur
-------------------------------
462 20
38
500 25
37
537 30
38
575 35
37
612 40
38
650 45
37
687 50
38
725 55
37
762 60
38
800 65
37
837 70
38
875 75
37
912 80
38
950 85
37
987 90
Bingo! Die Differenzen sind (im wesentlichen) immer gleich.
Dass die Differenzen abwechselnd 37 und 38 sind, ist ein deutliches
Indiz, dass das was mit Rundungen zu tun hat. D.h. die Differenz des ADC
Wertes für jeweils 5° ist eigentlich 37.5, und da wurde dann einmal 37
genommen und einmal 38. Also einmal ein bischen zu wenig, dafür das
nächste mal ein bischen zuviel - damit sich der Fehler über die ganze
Tabelle gesehen aufhebt.
Wie kann ich jetzt die ADC Werte in eine Zahlenfolge 0, 1, 2, 3, 4, 5,
... verwandeln, so dass sich die einzelnen "Schubladen" der ADC Werte
ergeben und in dieser Folge wiederspiegeln?
Was ich will ist also das hier
ADC Temperatur
-------------------------------
462 20 0
500 25 1
537 30 2
575 35 3
612 40 4
650 45 5
687 50 6
725 55 7
762 60 8
800 65 9
837 70 10
875 75 11
912 80 12
950 85 13
987 90 14
Wie kann ich das erreichen.
Na wenn ich vom ADC Wert erst mal einfach nur 462 abziehe (warum? weil
das der kleinste Wert in der Tabelle ist!), dann kommt da raus
ADC Ziel ADC - 462
-------------------------------
462 0 0
500 1 38
537 2 75
575 3 113
612 4 150
650 5 188
687 6 225
725 7 263
762 8 300
800 9 338
837 10 375
875 11 413
912 12 450
950 13 488
987 14 525
gut. Schau ich mir diese neue Spalte an, dann finden sich die vorher
festgestellten 37.5 da drinn wieder. Alle Differenzen sind gerundete
Versionen eines Vielfachen dieser 37.5. Und, oh Wunder, genau die Zahl,
die unter 'Ziel' steht, sagt mir, das wievielte Vielfache von 37.5 das
ist.
Alles was ich tun muss, ist also nur diese Spalte durch 37.5 dividieren
und ich kriege (als ganze Zahl)
ADC Ziel ADC - 462 (ADC-462)/37.5
---------------------------------------------------------
462 0 0 0
500 1 38 1
537 2 75 2
575 3 113 3
612 4 150 4
650 5 188 5
687 6 225 .
725 7 263 .
762 8 300 .
800 9 338 .
837 10 375
875 11 413
912 12 450
950 13 488
987 14 525
und das stimmt auffallend mit der Spalte 'Ziel' überein.
Warum möchte ich das als aufsteigende Folge 0, 1, 2, 3, 4, ... haben?
Na, ganz einfach: weil ich jetz mit einer Umkehrung daraus ganz banal
die Temperaturwerte berechnen kann.
Die Temperatur steigt von einer Zeile zur nächsten um jeweils 5°, d.h.
multipliziere ich diese 'Schubfahnummer' mit 5, dann habe ich diesen
Anstieg bereits berücksichtigt. Und die erst Schublade, die mit der
Nummer 0, soll 20 Grad ergeben. Also zähle ich noch 20 dazu.
D.h. der ganze Code
und jetzt vergleich mal was einfacher ist. Die obere if-Orgie oder die
untere Berechnung, die nicht schwer zu finden war?
Was noch fehlt ist Fehlerbehandlung, wenn die ADC Werte nicht im
erwarteten Bereich sind, aber das wars dann auch schon!
Hier genauso
1
if((y==1)&&(i==1))//Wenn y==1 und i==1 ist,dann
2
{
3
4
OCR0=45;
5
6
7
}
8
9
if((y==1)&&(i==2))
10
{
11
OCR0=30;
12
13
}
14
if((y==1)&&(i==3))
15
{
16
OCR0=20;
17
}
18
if((y==1)&&(i==4))
19
{
20
OCR0=10;
21
22
}
23
if((y==1)&&(i==5))
24
{
25
OCR0=0;
26
27
}
28
29
//Automatich
30
31
if((y==0)&&(t==1))
32
{
33
34
OCR0=45;
35
}
36
37
if((y==0)&&(t==2))
38
{
39
OCR0=35;
40
41
}
42
if((y==0)&&(t==3))
43
{
44
OCR0=25;
45
}
46
if((y==0)&&(t==4))
47
{
48
OCR0=20;
49
50
}
51
if((y==0)&&(t==5))
52
{
53
OCR0=15;
54
55
if((y==0)&&(t==6))
56
{
57
OCR0=10;
58
}
59
if((y==0)&&(t==7))
60
{
61
OCR0=0;
62
63
}
nur mit dem Unterschied, dass die OCR Werte nicht so schön linear
ansteigen (also nicht immer dieselbe Differenz haben).
Was macht man da.
Na ganz einfach: man benutzt ein Array. t ist der Index ins Array und
aus dem Array kriegt man den einzustellenden OCR Wert.
1
intAutomaticPWM[]={45,35,25,20,15,10,0};
2
intManuellPWM[]={45,30,20,10,0};
3
4
5
....
6
7
8
if(mode==1){// auf Automatik!
9
if(t>7)// Sicherheitshalber, man kann sich ja auch
10
t=7;// verrechnen
11
OCR0=AutomaticPWM[t-1];
12
}
13
14
else{// Modus muss daher auf Manuell eingestellt sein
15
if(userSpeed>5)
16
userSpeed=5;
17
OCR0=ManuellPWM[userSpeed-1];
18
}
und wieder: fertig.
(Und wenn man die 'Einstellung' der Geschwindigkeitsstufe durch den
Benutzer, bzw. die Berechnung aus der Geschwindigkeit korrekt gemacht
hat, dann kann man sich die Angstabfragen sparen, ob die Indizes korrekt
sind, was den Code noch mal kleiner macht)
Alleine mit diesen beiden Änderung fallen grob gerechnet rund 80% eures
Codes weg! Und dadurch, dass jetzt plötzlich auf eine einzige
Bildschirmseite passt, verliert man auch nicht den Überblick im Code und
tut sich mit Änderungen viel leichter.
d.h. Ihr habt euch viel zu viel, richtig viel zu viel Arbeit gemacht,
indem ihr euch geweigert habt in den Zahlen erst mal nach Mustern zu
suchen. 3 Minuten Nachdenken und mit den Zahlen spielen hätten auch
mindestens 4 Stunden Arbeit erspart (die 4 Stunden hab ich jetzt aus dem
geschätzt, was ich im Code so sehe und mir vorstelle, wie ihr
verzweifelt versucht Fehler zu finden)
Das ist (im wesentlichen - ohne Berücksichtigung der Tastenauswertung)
alles was von eurem Machwerk übrig bleibt
1
...
2
intAutomaticPWM[]={45,35,25,20,15,10,0};
3
intManuellPWM[]={45,30,20,10,0};
4
5
...
6
7
intmain(void)
8
{
9
intmodus=1;// 1 ist Automatic, 0 ist Manuell
10
intuserSpeed=5;// Benutzereinstellbare Geschwindigkeitsstufen, 1 bis 5
TCCR1A=(1<<WGM11)|(1<<WGM10)|(1<<COM1A1);// 10bit-Counter, nicht invert. PWM
22
TCCR1B=(1<<CS10);// Pre-Scaler = 1, also ohne Teiler
23
24
lcdinit();
25
lcdclear();
26
27
while(1)
28
{
29
// ************** Tastenabfrage und Auswertung, was eigentlich
30
// zu tun ist
31
32
........
33
........
34
35
// ************** Temperatur Auswertung
36
adcWert=MESSWERT();
37
38
if(adcWert<462)
39
adcWert=462;
40
41
t=(adcWert-462)/37.5;
42
Temperatur=t*5+20;
43
44
lcdwritexy(1,1,"Temperatur:");
45
lcdwritedec(Temperatur);
46
47
t=t/2+1;
48
49
// ************** Lueftereinstellung
50
if(modus==1){// auf Automatik!
51
OCR0=AutomaticPWM[t-1];
52
}
53
54
else{// Modus muss daher auf Manuell eingestellt sein
55
OCR0=ManuellPWM[userSpeed-1];
56
}
57
58
_delay_ms(500);
59
60
}// end while( 1 )
61
}// end Funktion
und jetzt vergleich das mal (Ich habs nicht kompiliert, da mögen noch
kleinere Tippfehler drinnen sein und die Tastenauswertung bzw.
Benutzerseteuerung fehlt auch noch) mit deinem Original!
Es lohnt sich, wenn man im Vorfeld ein paar Minuten investiert und sich
überlegt, wie man die Dinge machen kann.
Schön langsam wundert mich das nicht mehr, dass Handy-Provider leichtes
Spiel haben, wenn Jugendliche sofort das Hirn abschalten, sobald sie
mehr als 2 Zahlen sehen und rausfinden müssen, wie man die miteinander
verrechnen kann. Ist ja auch so cool, wenn man sagen kann "In Mathe war
ich schon immer schlecht!"