Hallo Leute,
Zum Einarbeiten in die Arduino-Welt habe ich Neuling auf dem Steckbrett
eine Lüftersteuerung simuliert - mit Poti statt Sensor, LED und Oszi
statt Lüfter. Bei Erreichen einer bestimmten Temperatur startet PWM mit
etwa 10 % und mit zunehmender Temperatur werden die Pulse breiter.
Klappt so weit wunderbar.
Nun möchte ich aber, dass auch ein älterer, verstaubter Lüfter sicher
startet. Daher soll der Lüfter nicht mit nur 10 % Pulsbreite starten,
sondern für die ersten ein oder zwei Sekunden mit 100 %.
Ich krieg das einfach nicht hin, egal was ich auch versuche. :(
Hier der Code:
1
intpwmPin=6;// Lüfter
2
intt1Pin=A1;// Temperatursensor
3
intt1ValC(0);// Begrenzter Wert für Temperatursensor
4
intpwmVal(0);// Variable für die Pulsbreite
5
6
voidsetup()
7
{
8
pinMode(pwmPin,OUTPUT);// setzt Pin als Ausgang
9
}
10
11
voidloop()
12
{
13
intt1Val=analogRead(t1Pin);
14
t1ValC=constrain(t1Val,100,800);// brgrenzt min. und max. Wert
15
16
{
17
pwmVal=map(t1ValC,100,800,24,255);// rechnet begrenzten Wert von 100 - 800
18
}// in PWM 24 - 255 um (entspricht 10 - 100 % Pulsbreite)
kleiner Tipp: was im Setupbereich steht wird nur einmal ausgeführt.
Ansonsten macht man sich eine Variable die als Flag dient. Ist dieses
Flag nicht gesetzt wird die Funktion ausgeführt, bei gesetztem Flag
nicht.
bei 0% oder 100% setzt die PWM aus wenn ich mich recht erinnere, es geht
nur von 1%-99%, genauer von 1-255 oder war es 1-254 weil 255 keine PWM
mehr ist?
0 oder 255 ist Dauer low/high und keine PWM
alternativ, PWM Port nur auf out als PORT und nach Anlaufzeit auf PWM
umstellen.
@Joachim B. (jar)
>bei 0% oder 100% setzt die PWM aus wenn ich mich recht erinnere,
Was soll da aussetzen? 0% = dauerhaft LOW, 100% dauerhaft HIGH.
>es geht nur von 1%-99%
Nö. Ausserdem geht der Parameter von analog_write von 0-255.
>alternativ, PWM Port nur auf out als PORT und nach Anlaufzeit auf PWM>umstellen.
Nö, denn der Arduino nutzt die PWM im phase correct mode, da sind 0 und
100% sprich 0 und 255 kein Problem.
Im Setup möchte ich das aber nicht reinmachen. Denn der Lüfter soll ja
nicht beim Einschalten des Gerätes starten, sondern erst beim Erreichen
einer bestimmten Temperatur.
Ähm, was ist ein Flag, wie setzt man das und wo kommt das hin? Ich habe
bereits folgenden versucht:
Eine Variable namens "state" gesetzt und dann mit dem if-Befehl bei
analogwert > 100 state auf 1 gesetzt. Hat aber auch nicht geklappt.
Irgendwie steh ich auf dem Schlauch.
Danke inzwischen.
Falk B. schrieb:> Was soll da aussetzen? 0% = dauerhaft LOW, 100% dauerhaft HIGH.
mir war so bei einer invertierten LED Fading Geschichte ein 0 oder 255
machte nicht dunkel sondern volle Helligkeit, ich musste ja die original
LED Fading Tabelle bei einem LCD umdrehen weil es LCD mit HG Beleuchtung
gibt die invers arbeiten, die Kennlinie also nicht passte und mit 0 oder
255 war nix mit gedimmt weil der Zustand statisch wurde und eben volle
Helligkeit war statt voll dunkel.
Joe J. schrieb:> Eine Variable namens "state" gesetzt
Das ist schon mal eine gute Idee.
Der erste Schritt zu einem endlichen Automaten.
Mehr Zustände einführen!
1. Aus (startbedingung)
2. Anlauf (kurz auf Vollgas)
3. Regelung
@Joe J. (neutrino)
>Im Setup möchte ich das aber nicht reinmachen. Denn der Lüfter soll ja>nicht beim Einschalten des Gerätes starten, sondern erst beim Erreichen>einer bestimmten Temperatur.
Das sollte man sagen ;-)
>Ähm, was ist ein Flag, wie setzt man das und wo kommt das hin? Ich habe>bereits folgenden versucht:>Eine Variable namens "state" gesetzt und dann mit dem if-Befehl bei>analogwert > 100 state auf 1 gesetzt.
Erspar uns diese Lyrik, poste originalen Quelltext.
> Hat aber auch nicht geklappt.>Irgendwie steh ich auf dem Schlauch.Statemachine
1
intpwmPin=6;// Lüfter
2
intt1Pin=A1;// Temperatursensor
3
intt1ValC;// Begrenzter Wert für Temperatursensor
4
intpwmVal;// Variable für die Pulsbreite
5
intfan_state;// State machine
6
intdelay_cnt;
7
8
#define FAN_STATE_OFF 0
9
#define FAN_STATE_ON 1
10
#define FAN_STATE_DELAY 2
11
12
voidsetup()
13
{
14
pinMode(pwmPin,OUTPUT);// setzt Pin als Ausgang
15
fan_state=FAN_STATE_OFF;
16
}
17
18
voidloop()
19
{
20
intt1Val=analogRead(t1Pin);
21
t1ValC=constrain(t1Val,100,800);// begrenzt min. und max. Wert
22
23
switch(fan_state){
24
caseFAN_STATE_OFF:
25
if(t1ValC>200){
26
fan_state=FAN_STATE_DELAY;
27
delay_cnt=2;
28
pwmVal=0;
29
}
30
break;
31
32
caseFAN_STATE_DELAY:
33
delay_cnt--;
34
if(delay_cnt==0){
35
fan_state=FAN_STATE_ON;
36
}
37
break;
38
39
caseFAN_STATE_ON:
40
if(t1ValC<200){
41
fan_state=FAN_STATE_OFF;
42
pwmVal=0;
43
}else{
44
pwmVal=map(t1ValC,100,800,24,255);// rechnet begrenzten Wert von 100 - 800
45
// in PWM 24 - 255 um (entspricht 10 - 100 % Pulsbreite)
Das wäre ein schöner Troll-Thread für unseren Asm-Fanatiker.
Ein Tipp: schnapp dir ein Blatt Papier und mach ein Ablaufdiagrm. Dann
proggst du das schön nach...
Falk B. schrieb:> Das sollte man sagen ;-)
Ich dachte, das ging aus dem Eingangspost hervor...
Falk B. schrieb:> Erspar uns diese Lyrik, poste originalen Quelltext.
Es gibt nur den von mir bereits geposteten. Alle anderen Quelltexte,
welche ich mit ergoogelten Codestückchen zu erweitern versuchte, habe
ich frustriert wieder verworfen.
Dass ich ein Neuling bin, habe ich geschrieben. Vielleicht hätte ich
noch erwähnen sollen, dass ich von Programmiersprachen bis vor wenigen
Wochen absolut keine Ahnung hatte. Ich programmierte meine PICs bis
jetzt (bitte nicht lachen) immer mit Parsic.
Nun, mit den Begriffen #define, switch, case und break bin ich noch
absolut nicht vertraut. Ich werde mich morgen etwas damit beschäftigen
und versuchen deinen Code zu verstehen. :)
Vielen Dank für deine Mühe, Falk Brunner (falk)!
Gruß, Joe
Joe J. schrieb:> Nun, mit den Begriffen #define, switch, case und break bin ich noch> absolut nicht vertraut.
Darauf kann man verzichten.
Mit Zeiger auf Funktionen tuts das genau so gut.
@ Nobody (Gast)
>> Nun, mit den Begriffen #define, switch, case und break bin ich noch>> absolut nicht vertraut.>Darauf kann man verzichten.>Mit Zeiger auf Funktionen tuts das genau so gut.
Pädagogisch sehr sinnvoll für einen Anfänger . . .
Aber so ist es übersichtlicher.
case ist wie eine Akte voll Code zu verstehen
und switch die Entscheidungsmöglichkeit,
welche Akte voll Code ausgeführt wird.
Es werden also drei Fälle (engl. case) definiert,
für jeden deiner möglichen Zustände einer.
Und dann wird immer wieder (bei jedem loop) abgefragt, welcher Fall
gerade behandelt werden soll.
@ Falk Brunner:
Dein Code funktioniert leider nicht so wie gewünscht. "delay(1000)" ist
ständig aktiv, so dass auch das Drehen am Poti verzögert reagiert. Und
der Lüfter startet nicht mit Vollgas, sondern pwmVal entsprechend.
Aber Dank deines Codes und mit dem Link zur Statemachine (den Begriff
hatte ich vorher noch nie gehört) habe ich es nun endlich hingekriegt!
:-D
1
/*
2
Analoger Temperatureingang, PWM-Ausgang für Lüfter.
3
LCD ist nur für Testzwecke.
4
*/
5
6
#include<LiquidCrystal.h>
7
LiquidCrystallcd(12,11,5,4,3,2);// diese Pins werden benutzt (RS, E, D4, D5, D6, D7)
8
9
intpwmPin=6;// Lüfter
10
intt1Pin=A1;// Temperatursensor
11
intt1ValC(0);// Begrenzter Wert für Temperatursensor
12
intpwmVal(0);// Variable für die Pulsbreite
13
unsignedcharstate=1;// globale Variable, die den Status repräsentiert
14
15
voidsetup()
16
{
17
pinMode(pwmPin,OUTPUT);// setzt Pin als Ausgang
18
lcd.clear();// LCD löschen
19
lcd.begin(16,4);// verfügbare Spalten und Zeilen
20
}
21
22
voidloop()
23
{
24
25
intt1Val=analogRead(t1Pin);
26
t1ValC=constrain(t1Val,100,800);// brgrenzt min. und max. Wert
27
pwmVal=map(t1ValC,100,800,24,255);// rechnet begrenzten Wert von 100 - 800
28
// in PWM 24 - 255 um (entspricht 10 - 100 % Pulsbreite)
29
lcd.clear();
30
lcd.setCursor(0,0);
31
lcd.print(t1Val);
32
lcd.setCursor(0,1);
33
lcd.print(pwmVal);
34
lcd.setCursor(0,2);
35
lcd.print(state);
36
delay(50);
37
38
39
switch(state){
40
case1://Temperatur niedrig, Lüfter aus..
41
if(t1Val<100)
42
{
43
analogWrite(pwmPin,0);
44
state=1;
45
}else{//.. ansonsten schalte auf case 2
46
state=2;
47
}
48
break;
49
50
case2://Lüfter startet für 2 s Vollgas
51
if(t1Val>=100)analogWrite(pwmPin,255);
52
delay(2000);
53
state=3;//schalte auf case 3
54
break;
55
56
case3://Lüfter läuft mit Wert "pwmVal"
57
if(t1Val>=100)
58
{
59
analogWrite(pwmPin,pwmVal);
60
}elseif(t1Val<90){//Temperatur zu niedrig, schalte auf case 1
61
state=1;
62
}
63
break;
64
}
65
}
Toll ist auch, dass ich den Ausschaltwert in case 3 niedriger als den
Einschaltwert setzen konnte; dadurch erhält man eine Hysterese.
Womöglich setze ich diesen Code tatsächlich mal ein einem Labornetzteil,
Ladegerät o.ä. ein.
Vielen Dank an falk und auch den anderen für die Beiträge!
Gruß, Joe