Forum: Mikrocontroller und Digitale Elektronik Arduino: Stroboskop PWM


von Ecd E. (ecd)


Lesenswert?

Hallo,

ein Kumpel und ich bauen gerade an einem naja etwas größerem LED 
Stroboskop mit 8x 100W LED's die Hardware steht im großen und ganzem, 
zum Steuern haben wir uns für ein Arduino entschieden.

Mit dem Programm soll man u.a die Helligkeit der LED und derren 
Blitzgeschwindkeit regeln.
Sprich ein Ausgang wird EIN und AUSGESCHALTEN (Blink-Geschwindkeit) und 
parallel dazu wird der selbige Ausgang mit PWM beschrieben (Helligkeit)
Die Werte für die Helligkeit und Geschwindkeit soll er sich von 2 
Variablen holen, die dann später per Taster inkrementiert bzw. 
dekrementiert werden.

Am Ausgangs Pin des Arduino hängt ein Tranistor der praktisch den 
LED-Treiber steuert (hat ein PWM Eingang)

Als wir mit einer LED angefangen haben um das  ganze zu testen haben wir 
uns dieses Programm zurecht gestrickt, das die Helligkeits und 
geschwindkeits werte von 2 Potis ausliest - das hat auch wunderbar 
funktioniert.
Mit dem neuem Code, ohne Potis, mit Tastern, will das ganze nicht. Wir 
machen da seit einer Woche dran rum un finden unseren Denkfehler nicht.
Villeicht könnt ihr uns helfen :) ?

Altes Programm mit Potis - FUNKTIONIERT:
1
/* Blink without Delay
2
 
3
 Turns on and off a light emitting diode(LED) connected to a digital  
4
 pin, without using the delay() function.  This means that other code
5
 can run at the same time without being interrupted by the LED code.
6
 */
7
8
// constants won't change. Used here to
9
// set pin numbers:
10
const int ledPin =  11;      // the number of the LED pin
11
12
// Variables will change:
13
int ledState = LOW;             // ledState used to set the LED
14
long previousMillis = 0;        // will store last time LED was updated
15
16
// the follow variables is a long because the time, measured in miliseconds,
17
// will quickly become a bigger number than can be stored in an int.
18
long interval;           // interval at which to blink (milliseconds)
19
int Helligkeit = 0;       // Variable für den ADC Wert vom Freq Poti
20
long potiFrequenz = 0;    // INPUT Poti Frequenz
21
int potiHelligkeit = 1;
22
void setup() {
23
  // set the digital pin as output:
24
  pinMode(ledPin, OUTPUT);      
25
}
26
27
void loop()
28
{
29
  // here is where you'd put code that needs to be running all the time.
30
31
  // check to see if it's time to blink the LED; that is, if the
32
  // difference between the current time and last time you blinked
33
  // the LED is bigger than the interval at which you want to
34
  // blink the LED.
35
  unsigned long currentMillis = millis();
36
 interval = analogRead(potiFrequenz);    // Analog Wert lesen
37
  
38
  if(currentMillis - previousMillis > interval) {
39
    // save the last time you blinked the LED
40
    previousMillis = currentMillis;  
41
42
    // if the LED is off turn it on and vice-versa:
43
    if (ledState == LOW)
44
      ledState = HIGH;
45
    else
46
      ledState = LOW;
47
48
    // set the LED with the ledState of the variable:
49
    digitalWrite(ledPin, ledState);
50
    }
51
if (ledState == HIGH)
52
{Helligkeit = analogRead(potiHelligkeit);   // liest den Input Pin
53
analogWrite(ledPin, Helligkeit / 4);  // analogRead Werte reichen von 0 to 1023, analogWrite Werte von 0 to 255 
54
}
55
}

und hier unser neues Programm - funktioniert nicht
1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
// Projekt: 800W LED Stroboskop
3
// Projektdatum: August 2014       
4
// Ersteller: J&L
5
// Software Version 4.9
6
//
7
//
8
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9
10
11
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12
//                                           EINGÄNGE
13
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
14
const int I_freigabe = 2;                             // Freigabe Taster (N.O), an PIN 
15
const int I_gh = 4;                                  // Geschwindigkeit (1) oder Helligkeits (0)  Wahlschalter (N.O), an PIN 
16
const int I_remote = 7;                             // Remote Wahlschalter (N.O), an PIN
17
const int I_inc = 8;                               // Inkrement Taster (N.O), an PIN 
18
const int I_dec = 10;                              // Inkrement Taster (N.O), an PIN 
19
const int I_temp = A0;                                // PT 100 Temperatur Sensor über Spannungsteiler an ANALOG PIN 0
20
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21
//                                           VARIABLEN
22
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23
int X_freigabe = 0;                     // Freigabe Taster (N.O), an PIN 
24
int X_gh = 0;                          // Geschwindigkeit (1) oder Helligkeits (0)  Wahlschalter (N.O), an PIN 
25
int X_remote = 0;                     // Remote Wahlschalter (N.O), an PIN
26
int X_inc = 0;                       // Inkrement Taster (N.O), an PIN 
27
int X_dec = 0;                      // Inkrement Taster (N.O), an PIN 
28
int X_temp = 0;                        // PT 100 Temperatur Sensor über Spannungsteiler an PIN
29
long X_helligkeit = 1023.0;                 // Helligkeitswert 
30
long X_geschwindigkeit = 6000.0;           // Geschwindigkeitswert
31
32
int X_ledState_1 = 0;            // Speicher aktueller LED Zustand
33
34
long X_previousMillis_1 = 0;         // Speicher für Geschwindigkeit in ms
35
36
37
unsigned long X_currentMillis_2 = millis();
38
unsigned long X_currentMillis_3 = millis();
39
unsigned long X_currentMillis_4 = millis();
40
long pause = 200;
41
long zeitschalter = millis();
42
43
44
// Für Freigabe
45
int X_freigabestatus = LOW;
46
int X_freigabepre = LOW;
47
long time = 0;
48
long debounce = 200;
49
50
int X_handstatus = 0;
51
int X_remotestatus =0;
52
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
53
//                                           AUSGÄNGE
54
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
55
const int O_pwm1 = 3;                // PWM Ausgang Nr 1 an PIN 3
56
const int O_freigabe = 11;            // Freigabe Ausgang für das Netzteil an PIN 11
57
const int O_ready = 12;               // LED Ausgang Betriebsbereit an PIN 12
58
const int O_overtemp = 13;            // LED Ausgang Übertemperatur an PIN 13
59
60
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
61
//                                           SETUP
62
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63
void setup() 
64
{
65
// EINGÄNGE deklarieren
66
pinMode(I_freigabe, INPUT);
67
pinMode(I_gh, INPUT);
68
pinMode(I_remote, INPUT);
69
pinMode(I_inc, INPUT);
70
pinMode(I_dec, INPUT);
71
pinMode(I_temp, INPUT);
72
73
// AUSGÄNGE deklarieren
74
pinMode(O_pwm1, OUTPUT);
75
pinMode(O_freigabe, OUTPUT);
76
pinMode(O_ready, OUTPUT);
77
pinMode(O_overtemp, OUTPUT);
78
79
// SERIELLE SCHNITTSTELLE initialisieren
80
Serial.begin(9600); // 9600 Baud
81
}
82
83
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84
//                                           MAIN ROUTINE, hier beginnt das eigentliche Programm
85
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86
void loop() 
87
{
88
// Eingänge in die Variablen übertragen (PROZESSABILD der EINGÄNGE)
89
X_freigabe= digitalRead(I_freigabe);
90
X_gh=       digitalRead(I_gh);
91
X_remote=   digitalRead(I_remote);
92
X_inc=      digitalRead(I_inc);
93
X_dec=      digitalRead(I_dec);
94
X_temp=     analogRead(I_temp);
95
96
97
/* Status der Variablen zur seriellen Schnittstelle schieben
98
IST IM MOMENT "AUSGESCHALTEN"
99
Serial.println ("Remotestatus:");
100
  Serial.println(X_remotestatus);
101
Serial.println ("-------");
102
Serial.println ("Handstatus");
103
  Serial.println(X_handstatus);
104
Serial.println ("-------");
105
Serial.println ("Hellikeit");
106
  Serial.println(X_helligkeit);
107
Serial.println ("-------");
108
Serial.println ("Geschwindkeit");
109
  Serial.println(X_geschwindigkeit);
110
Serial.println ("-------");
111
Serial.println ("O PWm1");
112
  Serial.println(O_pwm1);
113
Serial.println ("-------");
114
delay (2000); // 2s warten
115
116
*/
117
118
119
120
// 00 ---- Sicherheiten und TEMP abfrage
121
122
123
// 01 ---- Freigabe
124
// Ist X_freigabe HIGH  UND X_temp KLEINER 55GRAD Celsius, dann schalte O_freigabe auf HIGH
125
// Schalte O_freigabe auf LOW WENN X_temp GRÖSSER 55 GRAD Celsius (vorerst) ODER X_Freigabe ERNEUT HIGH IST
126
127
if (X_freigabe == 1 && X_temp <= 55 && X_freigabepre == 0 && millis() - time > debounce)
128
{
129
if (X_freigabestatus == 1)
130
X_freigabestatus = 0;
131
else
132
X_freigabestatus = 1;
133
time = millis();
134
}
135
if (X_temp > 55)
136
{
137
  X_freigabestatus = 0;
138
}
139
140
digitalWrite(O_freigabe, X_freigabestatus);
141
X_freigabepre = X_freigabe;
142
143
// 02 ---- Remote
144
// Ist X_remote HIGH ignoriere die Befehle vom Bedienfeld (Außer Freigabe)
145
// Ist X_remote LOW ignoriere die Befehle von Remote
146
if (X_freigabestatus == HIGH)
147
{ 
148
  if ((X_remote == HIGH) && (X_freigabestatus == 1))
149
{ 
150
 // 03 ---- REMOTE und WEBOBERFLÄCHE
151
X_remotestatus = 1;
152
X_handstatus = 0;
153
}
154
else
155
{
156
// 04 ---- HANDBETRIEB 
157
X_handstatus = 1;
158
X_remotestatus = 0;
159
160
// 4.1 ---- Wahlschalter für Geschwindkeit oder Helligkeit, inkremente und dekremente
161
// Ist X_gh HIGH dann bedeutet das GESCHWINDIGKEIT, ist X_gh LOW dann HELLIGKEIT
162
163
if (X_gh == LOW);                                     // Wahlschalter: HELLIGKEIT ist angewähält
164
{
165
if (X_inc == HIGH)                                    // Inkrementtaster gedrückt ?
166
{ 
167
X_helligkeit = X_helligkeit +51;                     // Inkrementiere X_helligkeit um 51
168
}
169
if (X_dec == HIGH)                                  // Decrementtaster gedrückt ?                 
170
{ 
171
X_helligkeit = X_helligkeit -51;                    // Dekrementiere X_helligkeit um 51
172
}
173
}   
174
if (X_gh == HIGH);                           // Wahlschalter: GESCHWINDKEIT ist angewählt
175
{  
176
if (X_inc == HIGH)                              
177
{ 
178
X_geschwindigkeit = X_geschwindigkeit +51;           
179
}
180
if (X_dec == HIGH)                             
181
{ 
182
X_geschwindigkeit = X_geschwindigkeit -51;
183
}
184
185
// Überlauf: Die Helligkeit und die Geschwindkeit dürfen nicht größer 255 sein, wenn ja setze zurück auf 0
186
187
if (X_helligkeit > 255.0)                                  
188
{ 
189
(X_helligkeit = 0.0); 
190
}
191
if (X_geschwindigkeit > 255.0)                              
192
{ 
193
(X_geschwindigkeit = 0.0); 
194
}
195
}
196
}  
197
}  
198
// 05 ---- AUSGANGSTUFEN 
199
200
// 05.1 ---- Ausgangstufe 1  
201
unsigned long X_currentMillis_1 = millis();
202
if(X_currentMillis_1 - X_previousMillis_1 > X_geschwindigkeit)   // Auswertung Blink geschwindigkeit 
203
{
204
X_previousMillis_1 = X_currentMillis_1;                      // letzten Wert überschreiben
205
206
if (X_ledState_1 == LOW)                   // LED Ein/Ausschalten abhängig vom aktuellen Zustand
207
{                               
208
analogWrite(O_pwm1, X_helligkeit);
209
X_ledState_1 = HIGH;
210
}
211
else 
212
{
213
analogWrite(O_pwm1, 0); 
214
X_ledState_1 = LOW;
215
}
216
}
217
}

Schonmal Danke für's drüber schauen

Gruß
Leo

von Karol B. (johnpatcher)


Lesenswert?

Ecd Ecd schrieb:
> und hier unser neues Programm - funktioniert nicht

Denkbar ungünstige Fehlerbeschreibung die ein gezieltes Suchen nach dem 
Problem im Prinzip unmöglich macht.

Ich weiß natürlich nicht wie viel Programmiererfahrung ihr schon habt, 
aber Kommentare wie dieser

Ecd Ecd schrieb:
> // Inkrementiere X_helligkeit um 51

sind ein Musterbeispiel für unnötige Kommentare. Das die Variable um 51 
inkrementiert wird, sieht man auf den ersten Blick, der Kommentar sollte 
eher beantworten warum inkrementiert wird. Überhaupt, wo kommt 
eigentlich der Wert 51 her? Das sieht mir nach einer "magischen" 
Konstante aus, und die sollte man als Konstante bzw. Makro definieren 
und gut kommentieren.

Ansonsten erscheint mir euer Programm unnötig kompliziert. Wenn ich das 
richtig sehe, dann generiert ihr das PWM Signal in der Hauptschleife 
"manuell". Gleichzeitig bremst ihr die Hauptschleife aber in jeder 
Iteration für 2 Sekunden aus. Das verträgt sich nicht sonderlich gut.

Der richtige Ansatz wäre es wohl das PWM Signal mittels Timer und einem 
Output Compare Register zu generieren (also wirklich in Hardware). In 
einer Timer ISR könnt ihr dann die eigentliche Stroboskop Funktion 
implementieren, indem ihr das Generieren des PWM Signals durch 
Beschreiben der entsprechenden Konfigurationsregister des Timers an- 
bzw. ausschaltet. Keine Ahnung wie gut sich das mit dem Arduino-Gedöns 
umsetzen lässt, aber soweit ich informiert bin, gibt es auch hierfür 
entsprechende Bibliotheken ;).

Mit freundlichen Grüßen,
Karol Babioch

: Bearbeitet durch User
von Ecd E. (ecd)


Lesenswert?

Karol Babioch schrieb:
> Ecd Ecd schrieb:
>> und hier unser neues Programm - funktioniert nicht
>
> Denkbar ungünstige Fehlerbeschreibung die ein gezieltes Suchen nach dem
> Problem im Prinzip unmöglich macht.

Sorry - das hatte ich komplett vergessen.
Und zwar, kann ich nun ganz gut die Geschwindkeit, also den Blinktakt 
verstellen, aber an der Helligkeit tut sich nicht wirklich etwas. (Indem 
ich oben die Variablen X_helligkeit und X_geschwindigkeit "hart" von 
außen mit einem Wert beschreibe.

Wir haben uns das follgendermaßen gedadacht:
Die Werte für Geschwindkeit und Helligkeit stehen in den Variablen:
X_helligkeit und X_geschwindigkeit diese sind normalerweise auf "0" 
gesetzt.

Es wird ein Wahlschalter abgefragt mit dem ich zwischen den zwei 
Variablen wechseln kann: Sprich ist der schalter  (I_gh) High ist die 
Geschwindkeit gemeint.
Drücke ich nun einmal auf den Inkrement Taster zählt der zur 
Geschwindkeit "51" dazu - 51 weil 5mal 51 255 ergibt (Vollgas) - (5 
Stufen)
Das gleiche passiert rückwärts wenn man den Dekrement Taster drückt.
und für die Helligkeitsvariable dann wenn der Wahlschalter eben Low ist.

Karol Babioch schrieb:
> Gleichzeitig bremst ihr die Hauptschleife aber in jeder
> Iteration für 2 Sekunden aus. Das verträgt sich nicht sonderlich gut.

Das war nur ein Test um die Werte der Variablen anzuzeigen im Serial 
Monitor - ist aber AUSGESCHALTEN weil AUSGEKLAMMERT. Sprich das ist 
nicht der Punkt.

Gruß Leo

P.S wir haben in Siemens S7 Programmiererfahrungen, aber das ist ein 
bisschen anderst wie mit dem Arduino, wegen der echtzeit... Ich denke 
das auch hier irgendwo unser Denkfehler liegt...

: Bearbeitet durch User
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.