Hallo Zusammen,
habe folgendes Problem. Ich möchte eine LED über ein Potentiometer
dimmen.
Meine vorgehensweise besteht darin in einer Schleife den aktuellen ADC
Wert (Potistellung) zu speichern und diesen als Duty-Cycle für die PWM
zu verwenden. Der ADC Wert liegt im Bereich 0...1023. Diesen will ich
normieren damit er im Bereich 0...100 liegt. Hier erstmal der gesamte
Code:
1 | #define clearbit(P,BIT) ((P) &= ~(1<<(BIT)))
|
2 | #define setbit(P,BIT) ((P) |= (1<<(BIT)))
|
3 |
|
4 | int main(void)
|
5 | {
|
6 | unsigned int adc_value;
|
7 |
|
8 | setbit(DDRB,0);
|
9 | setbit(PORTB,0);
|
10 |
|
11 | ADMUX = 0b01000000;
|
12 | ADCSRA = 0b11100100;
|
13 |
|
14 | uint8_t pwm_soll = 100; // gewünschter Dimmerwert 0..100
|
15 | uint8_t pwm_phase = 0; // Laufwert der Schleife 0..100
|
16 |
|
17 | setbit(DDRB, PB0); // PORTB PB0 als Ausgang
|
18 |
|
19 | while( 1 )
|
20 | {
|
21 | adc_value = ADCL;
|
22 | adc_value |= (ADCH << 8);
|
23 |
|
24 | pwm_soll = adc_value*100/1023; //Version 1
|
25 | //pwm_soll = adc_value*100.0/1023.0; //Version 2
|
26 |
|
27 | if( pwm_soll == pwm_phase )
|
28 | {
|
29 | setbit(PORTB ,PB0); // LED aus
|
30 | }
|
31 |
|
32 | pwm_phase++;
|
33 |
|
34 | if( pwm_phase == 100 )
|
35 | {
|
36 | pwm_phase = 0;
|
37 | clearbit(PORTB ,PB0); // LED an
|
38 | }
|
39 | }
|
40 |
|
41 | return 0;
|
42 |
|
43 | }
|
Von der Logik her müsste die Software ja funktionieren
Das Problem findet bei dieser Zuweisung statt:
pwm_soll = adc_value*100/1023;
Nach längerem forschen habe ich wohl das Problem gefunden.
Falls adc_value den wert 655 überschreitet und mit 100 multipliziert
wird, wird ein ergebnis von über 16 Bit erzielt. Das überschreitet den
Bereich des unsigned Int. Der Rest wird einfach abgeschnitten. D.h.
Falls ich mit meinem Poti diesen Wert überschreite fängt die LED wieder
von 0 an zu dimmen. Danach habe ich es mit dieser Zuweisung versucht:
pwm_soll = adc_value*100.0/1023.0;
Das funktioniert aber leider überhaupt nicht. Die LED blinkt nur noch.
Man sieht kein durchgängiges Leuchten mehr. Ist es dann nicht so, dass
mit double Werten gerechnet wird? Oder wird dann mit float Werten
gerechnet?
Ein anderer Versuch wäre noch:
pwm_soll = (adc_value*10)/102.3;
Bringt leider genauso wenig.
Ich hoffe ihr könnt mir helfen. Danke im Vorraus
mfg Alex