Forum: Mikrocontroller und Digitale Elektronik Arduino: 4-Pin Lüfter via PWM ansteuern - nur zwei Geschwindigkeiten?


von David (Gast)


Lesenswert?

Ich habe einen 4-Pin Lüfter an mein Arduino-Board nach folgendem Plan 
angeschlossen: http://i.stack.imgur.com/cmwAy.jpg, der Lüfter erhält 
seinen Strom von einer externen Quelle und nicht vom Arduino.

Mein Plan ist es, den Lüfter via Bluetooth fernzusteuern. Die Signale 
kommen auch an, der Lüfter reagiert auch auf meine eingaben. Allerdings 
scheint es, als würde ich nur zwei Geschwindigkeiten einstellen können, 
schnell und langsam.

Ich habe viele verschiedene Sketches zum steuern versucht. Zwischendurch 
kam ich auf die Bibliothek "SoftPWM" 
(https://code.google.com/p/rogue-code/wiki/SoftPWMLibraryDocumentation), 
die hat mir leider auch nicht weiterhelfen können.

Reicht es nicht aus, den gewünschten Wert an den PWM-Pin zu senden?

Mein aktueller Sketch (Ohne BT input, sondern mit Testvalues):
1
int fanPulse = 0;
2
unsigned long pulseDuration;
3
4
void setup()
5
{
6
Serial.begin(9600);
7
pinMode(fanPulse, INPUT);
8
digitalWrite(fanPulse,HIGH);
9
}
10
11
void readPulse() {
12
pulseDuration = pulseIn(fanPulse, LOW);
13
double frequency = 1000000/pulseDuration;
14
15
Serial.print("pulse duration:");
16
Serial.println(pulseDuration);
17
18
Serial.print("time for full rev. (microsec.):");
19
Serial.println(pulseDuration*2);
20
Serial.print("freq. (Hz):");
21
Serial.println(frequency/2);
22
Serial.print("RPM:");
23
Serial.println(frequency/2*60);
24
25
}
26
27
void loop()
28
{
29
analogWrite(12,20);
30
Serial.println(20);
31
delay(4000);
32
readPulse();
33
analogWrite(12,50);
34
Serial.println(50);
35
36
delay(4000);
37
readPulse();
38
analogWrite(12,100);
39
Serial.println(100);
40
41
delay(4000);
42
readPulse();
43
analogWrite(12,200);
44
Serial.println(200);
45
46
delay(5000);
47
readPulse();
48
analogWrite(12,255);
49
Serial.println(255);
50
51
delay(4000);
52
readPulse();
53
}

Resultat: Beschleunigen will der Lüfter erst ab einem Wert von 200, die 
Erhöhung auf 255 macht keinen Unterschied)
1
20
2
pulse duration:70511
3
time for full rev. (microsec.):141022
4
freq. (Hz):7.00
5
RPM:420.00
6
50
7
pulse duration:87106
8
time for full rev. (microsec.):174212
9
freq. (Hz):5.50
10
RPM:330.00
11
100
12
pulse duration:89900
13
time for full rev. (microsec.):179800
14
freq. (Hz):5.50
15
RPM:330.00
16
200
17
pulse duration:11879
18
time for full rev. (microsec.):23758
19
freq. (Hz):42.00
20
RPM:2520.00
21
255
22
pulse duration:12229
23
time for full rev. (microsec.):24458
24
freq. (Hz):40.50
25
RPM:2430.00
26
20
27
pulse duration:68764
28
time for full rev. (microsec.):137528
29
freq. (Hz):7.00
30
RPM:420.00
31
50
32
pulse duration:88380
33
time for full rev. (microsec.):176760
34
freq. (Hz):5.50
35
RPM:330.00

Ich bin langsam am Verzweifeln... Das Netz ist voller Tutorials, die 
PWM-Steuerung nach diesem Schema versprechen, aber das scheint nicht so 
zuverlässig zu funktionieren. Muss ich auch auf dem Arduino mehr 
berücksichtigen, als ich glaube? Wo liegt der Fehler und wie kann ich 
das Problem beheben?

David

von holger (Gast)


Lesenswert?

Mach das doch mal so:

void loop()
{
analogWrite(12,20);
}

Und dann so:

void loop()
{
analogWrite(12,200);
}

Tut sich was?

von Werner P. (Gast)


Lesenswert?

ich sehe nur 3 Anschlüsse am Lüfter. Gelb ist in der Regel das 
Tachosignal vom Lüfter.

von Markus (Gast)


Lesenswert?

David schrieb:
> Ich habe einen 4-Pin Lüfter an mein Arduino-Board nach folgendem Plan
> angeschlossen: http://i.stack.imgur.com/cmwAy.jpg,

Auf dem Bild sind aber nur 3 Anschlüsse. Wie hast den 4-Pin Lüfter in 
Wirklichkeit angeschlossen?

David schrieb:
> pinMode(fanPulse, INPUT);
> digitalWrite(fanPulse,HIGH);

Etwas stimmt hier nicht, Eingang oder Ausgang?

von Thomas V. (tommy_v)


Lesenswert?

Die Schaltung in deinem link ist nur zum Messen der Drehzahl geeignet.
"Reading Fan RPM via Arduino"

von David W. (david2k)


Lesenswert?

Die Pins habe ich natürlich nicht so wie im Plan anschließen können, es 
ging mir mehr um die Stromversorgung. Der Eingang für PWM liegt auf Pin 
12 und diesem sende ich auch die Signale zu.


Ich habe den Source mal krass umgeschrieben und kann jetzt wirklich 
präzise steuern, wenn ich aber das Signal über Bluetooth auslese, kann 
ich den Wert nicht einstellen, obwohl er korrekt ist. Ich Übergebe Werte 
zwischen 0 und 999.


Experimenteller Code, mit dem ich PWM exakt steuern kann:
1
void setup()
2
{
3
  pinMode(12, OUTPUT);
4
}
5
6
void loop()
7
{
8
  digitalWrite(12, HIGH);
9
  delayMicroseconds(100); // Approximately 10% duty cycle @ 1KHz
10
  digitalWrite(12, LOW);
11
  delayMicroseconds(1000 - 100);
12
}

Muss ich hier irgenwie Nebenläufigkeit einsetzen oder wieso sollte das 
über BT nicht mehr funktionieren?


Mein Code mit BT Input. Der Lüfter wird langsamer...das wars auch. Keine 
Kontrolle:
1
#include <SoftwareSerial.h>
2
#include <sstream> //für stringstream 
3
using namespace std;
4
5
int bluetoothTx = 2;
6
int bluetoothRx = 3;
7
int fanPulse = 7;
8
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
9
int i =0;
10
11
12
13
void setup()
14
{
15
 
16
17
  //Setup usb serial connection to computer
18
  Serial.begin(9600);
19
    SoftPWMBegin();
20
21
pinMode(6,OUTPUT);
22
  //Setup Bluetooth serial connection to android
23
  bluetooth.begin(115200);
24
  bluetooth.print("$$$");
25
  delay(100);
26
  bluetooth.println("U,9600,N");
27
  bluetooth.begin(9600);
28
  }
29
String currentValue="";
30
void loop()
31
{
32
   setpwm();
33
34
   //Read from bluetooth and write to usb serial
35
  if(bluetooth.available())
36
  {
37
    char toSend = (char)bluetooth.read();
38
39
    if(toSend =='?'){
40
41
//INTS
42
sscanf(currentValue.c_str(),"%d",&i);
43
currentValue="";
44
45
}else{
46
currentValue+=toSend;
47
}
48
  //  Serial.print(toSend);
49
  }
50
51
  //Read from usb serial to bluetooth
52
  if(Serial.available())
53
  {
54
    char toSend = (char)Serial.read();
55
    bluetooth.print(toSend);
56
  }
57
}
58
59
 void setpwm(){
60
61
analogWrite(12,HIGH);
62
delayMicroseconds(i);
63
digitalWrite(12,LOW);
64
delayMicroseconds(1000-i);
65
Serial.println(i);
66
67
 }

: Bearbeitet durch User
von Markus (Gast)


Lesenswert?

David Wilms schrieb:
> Die Pins habe ich natürlich nicht so wie im Plan anschließen können

aber dann bitte einen Schaltplan zeigen, der deinem Aufbau entspricht!


David Wilms schrieb:
> void setpwm(){
>
> analogWrite(12,HIGH);
> delayMicroseconds(i);
> digitalWrite(12,LOW);
> delayMicroseconds(1000-i);

Ja was jetzt, analogWrite() oder digitalWrite() ??
Für PWM ist analogWrite() vorgesehen.
Die Warterei mit delayMicroseconds läst keine Zeit für anderes zu...
http://arduino.cc/de/Reference/AnalogWrite

von David W. (david2k)


Lesenswert?

Markus schrieb:
> David Wilms schrieb:
>> Die Pins habe ich natürlich nicht so wie im Plan anschließen können
>
> aber dann bitte einen Schaltplan zeigen, der deinem Aufbau entspricht!
>
>
> David Wilms schrieb:
>> void setpwm(){
>>
>> analogWrite(12,HIGH);
>> delayMicroseconds(i);
>> digitalWrite(12,LOW);
>> delayMicroseconds(1000-i);
>
> Ja was jetzt, analogWrite() oder digitalWrite() ??
> Für PWM ist analogWrite() vorgesehen.
> Die Warterei mit delayMicroseconds läst keine Zeit für anderes zu...
> http://arduino.cc/de/Reference/AnalogWrite

Hoppla, da war es schon etwas später ;).

Leider funktioniert die aktualisierte Version auch nicht. Ich habe
1
i
 durch einen festen Wert ersetzt, das hat auch keine Auswirkung gehabt. 
Der Wert wird jedoch korrekt gesetzt, ich gebe ihn ja über die Konsole 
aus. Kann das am Bluetooth-Modul liegen?

1
void setpwm(){
2
3
analogWrite(12,HIGH);
4
delayMicroseconds(i);
5
analogWrite(12,LOW);
6
delayMicroseconds(1000-i);
7
Serial.println(i);
8
9
 }

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

David Wilms schrieb:

>
1
> void setpwm(){
2
> 
3
> analogWrite(12,HIGH);
4
> delayMicroseconds(i);
5
> analogWrite(12,LOW);
6
> delayMicroseconds(1000-i);
7
> Serial.println(i);
8
> 
9
>  }
10
>

Ganz ehrlich.
Ich versteh nicht was du da mit den Micorseconds rummachst.
Ein (1!) Aufruf von analogWrite reicht, und der Pin macht seine PWM. Und 
zwar ohne dein weiteres Zutun.
1
  analogWrite( 12, 28 );
setzt die PWM auf 28*100/256 = 10.9%

Aus, Ende. Mehr braucht es doch nicht.

Ausserdem. Aus der Arduino Doku
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
1
The Arduino's programming language makes PWM easy to use; simply call
2
analogWrite(pin, dutyCycle), where dutyCycle is a value from 0 to 255,
3
and pin is one of the PWM pins (3, 5, 6, 9, 10, or 11).

Man beachte: Pin 12 ist da nicht dabei.
Inweifern das bei bestimmten Arduino Modellen sich unterscheidet, weiß 
ich nicht. Aber ich würds fürs erste einfach nicht darauf ankommen 
lassen und mit dem System arbeiten anstatt gegen es.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

> Kann das am Bluetooth-Modul liegen?

Kannst du selber rauskriegen.
Schmeiss Bluetooth aus deinem Programm raus, steck den Shield ab und 
wenn es dann immernoch nicht geht, dann war Bluetooth wohl nicht Schuld.

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.