ADC-Wert -> LED Ausgabe

Gast #1074795
Lesenswert?

Hallo Forum,

ich habe einen AD-Port, an dem ich ein Poti habe. Ich lasse die Werte am 
Port wandeln (8 Bit). Das funktioniert bis hierhin.

Dann habe ich acht LEDs an acht Ports. P0-P7.

Bis jetzt habe ich das Ergebnis der AD-Wandlung auf die LEDs ausgegeben. 
Das funktioniert auch soweit. So wird das Ergebnis der AD-Wandlung quasi 
binär auf den LEDs ausgegeben. In etwa PortXY= ADCWert;

Nun würde ich aber gerne das ganze etwas anders ausgeben, aber auch 
wieder auf den LEDs.
Ich würde nun aber gerne mit steigendem ADCWert mehr LEDs angehen 
lassen.
Also 8 LEDs auf 8 Bit verteilt:

256/8= 32.

Wenn ADCWert= 0, soll keine LED leuchten, bei ADCWert 255 sollen alle 
acht LEDs leuchten. Wenn der ADCWert zwischen 1 und 32 liegt, soll die 
erste LED leuchten, wenn der ADCWert 32-64 ist, soll die erste und 
zweite LED leuchten usw.

Ich weiß leider nicht, wie ich das genau umsetzen soll. Ich könnte 
mehrere if / if else Abfragen nehmen oder das ganze über switch 
gestalten.

Wollte aber einmal fragen, ob es wohl möglich ist, das ganze einfacher 
zu gestalten, anstatt über viele Bedingungen.

Grüße
Volker
Gast #1074825
Lesenswert?

1. Eine Tabelle mit 8 Einträgen im Flash ablegen:

Tabelle:   ; "eine LED leuchtet" bis "alle 8 LEDs leuchten"
.DB 0b11111110, 0b11111100
.DB 0b11111000, 0b11110000
.DB 0b11100000, 0b11000000
.DB 0b10000000, 0b00000000

2. Den ADC-Wert 5 mal nach rechts schieben.  Das ergibt einen Wert 
zwischen 0 und 7. Diesen Wert als Index auf die Tabelle verwenden. 
Tabelleneintrag mit 'lpm' auslesen und auf den Port mit den LEDs 
schreiben.

Ich zähle 11 Assemblerbefehle für alles:
1
; 8-Bit-ADC-Rohwert in Register t
2
lsr t
3
lsr t
4
lsr t
5
lsr t
6
lsr t
7
ldi ZL, Low (2*Tabelle)
8
ldi ZH, High(2*Tabelle)
9
add ZL, t
10
adc ZH, _0       ; Register _0 immer = 0
11
lpm
12
out PORTB, r0

Falls Du auch noch den Zustand "alle LEDs aus" haben willst, wirds einen 
Tick komplizierter (selbst überlegen).
Gast #1074860
Lesenswert?

>Wenn ADCWert= 0, soll keine LED leuchten, bei ADCWert 255 sollen alle
>acht LEDs leuchten. Wenn der ADCWert zwischen 1 und 32 liegt, soll die
>erste LED leuchten, wenn der ADCWert 32-64 ist, soll die erste und
>zweite LED leuchten usw.

>Ich weiß leider nicht, wie ich das genau umsetzen soll. Ich könnte
>mehrere if / if else Abfragen nehmen oder das ganze über switch
>gestalten.
1
switch  (ADC_Wert>>5)
2
{
3
case 0:   PORTxy = 0b00000000;  break;
4
case 1:   PORTxy = 0b00000001;  break;
5
case 2:   PORTxy = 0b00000011;  break;
6
case 3:   PORTxy = 0b00000111;  break;
7
case 4:   PORTxy = 0b00001111;  break;
8
case 5:   PORTxy = 0b00011111;  break;
9
case 6:   PORTxy = 0b00111111;  break;
10
case 7:   PORTxy = 0b01111111;  break;
11
}
Gast #1074985
Lesenswert?

Hallo,

ich habe mal folgende Version getestet:
1
switch  (ADC_Wert>>5)
2
{
3
case 0:   PORTxy = 0b00000000;  break;
4
case 1:   PORTxy = 0b00000001;  break;
5
case 2:   PORTxy = 0b00000011;  break;
6
case 3:   PORTxy = 0b00000111;  break;
7
case 4:   PORTxy = 0b00001111;  break;
8
case 5:   PORTxy = 0b00011111;  break;
9
case 6:   PORTxy = 0b00111111;  break;
10
case 7:   PORTxy = 0b01111111;  break;
11
}

Ich hab das Problem, dass  von Anfang an die erste LED leuchtet und wenn 
ich dann an dem Poti drehe und die Spannung am ADC erhöhe, gehen weitere 
LEDs an bis acht Stück leuchten. eigentlich sollten doch nur 7 leichten 
maximal nach dem obigen code oder verstehe ich da was falsch und es 
sollte auch vorkommen, dass keine LED leuchtet, aber es leuchtet immer 
mindestens die erste LED.

Da steig ich nicht ganz durch.
Gast #1074995
Lesenswert?

Wahrscheinlich:

Wenn die LEDs wie üblich gegen VCC geschaltet sind, dann leuchten die 
acht LEDs wegen der Zeile "PORTxy = 0b00000000" und die eine LED am 
anderen Potiende leuchtet wegen der Zeile "PORTxy = 0b01111111".

>und die Spannung am ADC erhöhe

Erhöhst oder erniedrigst? Miss mal mit nem Multimeter direkt am Poti 
nach.
Gast #1075022
Lesenswert?

>Aber wie bekomme ich die achte LED zum leuchten?

Meine Operation ADC_Wert>>5 ist ja dasselbe wie eine Teilung durch 32.
Somit teilst du die 256Werte des Potis in 8 Zustände (0..7).

Willst du Null bis alle acht Leds leuchten lassen, musst du neun 
Zustände erzeugen.
1
switch  (  ADC_Wert / (uint8_t)(256/9)  )
2
{
3
case 0:   PORTxy = 0b11111111;  break;
4
case 1:   PORTxy = 0b11111110;  break;
5
case 2:   PORTxy = 0b11111100;  break;
6
case 3:   PORTxy = 0b11111000;  break;
7
case 4:   PORTxy = 0b11110000;  break;
8
case 5:   PORTxy = 0b11100000;  break;
9
case 6:   PORTxy = 0b11000000;  break;
10
case 7:   PORTxy = 0b10000000;  break;
11
case 8:   PORTxy = 0b00000000;  break;
12
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren