Forum: Mikrocontroller und Digitale Elektronik ADC-Wert -> LED Ausgabe


von Volker K. (Gast)


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

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Du kannst einen Schleifenzähler bauen der alle n ADC-Werte eine Variable 
erhöht bzw. deren Bits verschiebt, wie bei einem Bargraphen. Diese 
Variable gibst Du dann auf dem LED-Port aus.

von Gast (Gast)


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).

von Matthias L. (Gast)


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
}

von Volker K. (Gast)


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.

von Gast (Gast)


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.

von Volker K. (Gast)


Lesenswert?

Ahhhhhhh, ok ein Teil hat sich erledigt...Ich muss das ganze 
invertieren, um die LEDs zum leichten zu bringen......

Aber wie bekomme ich die achte LED zum leuchten?

von Matthias L. (Gast)


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
}

von Volker K. (Gast)


Lesenswert?

Hallo,

vielen Dank! Nun funktioniert es....Hab mal durch die Bitverschiebung 
wieder nicht ganz so durchgeblickt, bzw. mich mal wieder ein wenig 
verwirren lassen.


Vielen Dank.

Grüeß
Volker

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.