ADC-Wert -> LED Ausgabe

Gast #1074795
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
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
>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
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
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
>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
}
Gast
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.