ADC Werte für PWM nutzen - RGB LED Ansteuerung

elektronix00

Mitglied
02. Okt. 2008
30
0
6
62
Saarland
Sprachen
Hallo,

ich bin da wieder was am basteln, komme aber nicht weiter. Als µC habe ich den ATMEGA 88 gewählt, programmiert wird mit Bascom.

Ich möchte die 6 ADC Eingänge (ADC0 - ADC5) auswerten und diese Werte an die 6 PWM Ausgänge PB.1 bis PB.3 sowie PD.3, 5 und 6 ausgeben. Dort sollen später zwei RGB LEDs angeschlossen sein.
Also quasi ADC-Wert = PWM-Wert. Das Ganze mit diesen ADCs soll es mir ermöglichen, für jede der beiden RBB LEDs eine Farbe zu mischen. Später sollen an die Anschlüsse Leistungstransistoren und 2 RGB LED Stripes
dran, die dann bei einem bestimmten Ereignis zwischen den beiden eingestellten Farben wechseln soll.

Um mir zwischendurch mal die ADC bzw. PWM Werte anzeigen zu lassen, habe ich in der Testphase einfach mal ein 16 x 2 LCD angeschlossen und mit ins Programm eingebaut.
Weil meine Entwicklungsumgebung aber nur zwei Potis besitzt, habe ich den Code soweit gekürtzt, dass mir nur ADC0 sowie ADC1 angezeigt werden sollen.
Leider bekomme ich hier aber keine vernüntigen Werte angezeigt. Bei Trimmervollausschlag bekomme ich als Werte 255 und 255 angezeigt. Stelle ich die beiden Potis auf ca. Mitte, dann habe ich bei ADC0 den Wert 10 und bei ADC1 den Wert 27. Bei einer Viertelstellung sind es dann plötzlich 111 und 129. Potis in Nullstellung bringen dann wie erwartet jeweils 0 und 0.

Zu meinen Fragen: An was könnte das liegen, dass mir die ADC Werte nicht richtig angezeigt werden? Habe ich für später überhaupt die Umsetzung von ADC zu PWM richtig vorgenommen? Gibts vielleicht einen einfacheren Weg mein Idee umzusetzen?

Grüße Michael

Code:
'OC0A = PD.6 = Pin 12 - RGB LED_1 R
'OC0B = PD.5 = Pin 11 - RGB LED_2 R
'OC1A = PB.1 = Pin 15 - RGB LED_1 G
'OC1B = PB.2 = Pin 16 - RGB LED_2 G
'OC2A = PB.3 = Pin 17 - RGB LED_1 B
'OC2B = PD.3 = Pin 5  - RGB LED_1 B

'ADC0 = PC.0 = Pin 23
'ADC1 = PC.1 = Pin 24
'ADC2 = PC.2 = Pin 25
'ADC3 = PC.3 = Pin 26
'ADC4 = PC.4 = Pin 27
'ADC5 = PC.5 = Pin 28

$regfile = "m88adef.dat"
$crystal = 8000000
$hwstack = 100
$swstack = 100
$framesize = 100

'$PROG &HFF,&HE2,&HDF,&HF9' generated. Take care that the chip supports all fuse bytes.

Ddrb = &B11111111                                           'PortB = Ausgang
Portb = &B00000000                                          'und auf low gesetzt

Ddrc = &B00000000                                           'PortC = Eingang
Portc = &B00000000                                          'und auf low gesetzt

Ddrd = &B11111111                                           'PortD = Ausgang
Portd = &B00000000                                          'und auf low gesetzt


Rot_pwm1 Alias Ocr0a                                        'PWM-Output: Pin 12
Rot_pwm2 Alias Ocr0b                                        'PWM-Output: Pin 11
Gruen_pwm1 Alias Ocr1al                                     'PWM-Output: Pin 15
Gruen_pwm2 Alias Ocr1bl                                     'PWM-Output: Pin 16
Blau_pwm1 Alias Ocr2a                                       'PWM-Output: Pin 17
Blau_pwm2 Alias Ocr2b                                       'PWM-Output: Pin 05

Dim Adc0 As Byte
Dim Adc1 As Byte
Dim Adc2 As Byte
Dim Adc3 As Byte
Dim Adc4 As Byte
Dim Adc5 As Byte

Dim Rot_pwm1 As Byte
Dim Rot_pwm2 As Byte
Dim Gruen_pwm1 As Byte
Dim Gruen_pwm2 As Byte
Dim Blau_pwm1 As Byte
Dim Blau_pwm2 As Byte

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up
On Timer0 Timer0_pwm
Enable Timer0

Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up
On Timer1 Timer1_pwm
Enable Timer1

Config Timer2 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up
On Timer2 Timer2_pwm
Enable Timer2

Enable Interrupts

Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.4 , E = Portb.6 , Rs = Portb.7
Config Lcd = 16 * 2
Cls

Do

Adc0 = Getadc(0)
Adc1 = Getadc(1)
Adc2 = Getadc(2)
Adc3 = Getadc(3)
Adc4 = Getadc(4)
Adc5 = Getadc(5)

Rot_pwm1 = Adc0
Gruen_pwm1 = Adc1
Blau_pwm1 = Adc2
Rot_pwm2 = Adc3
Gruen_pwm2 = Adc4
Blau_pwm2 = Adc5

Locate 1 , 1
Lcd " " ; Rot_pwm1
Locate 1 , 5
Lcd " " ; Gruen_pwm1
Locate 1 , 10
Lcd " " ; Blau_pwm1

Locate 2 , 1
Lcd " " ; Rot_pwm2
Locate 2 , 5
Lcd " " ; Gruen_pwm2
Locate 2 , 10
Lcd " " ; Blau_pwm2

Locate 1 , 1
Lcd " " ; Adc0
Locate 1 , 5
Lcd " " ; Adc1
Locate 1 , 10
Lcd " " ; Adc2

Locate 2 , 1
Lcd " " ; Adc3
Locate 2 , 5
Lcd " " ; Adc4
Locate 2 , 10
Lcd " " ; Adc5


Waitms 500
Cls
Loop
End

Timer0_pwm:
Rot_pwm1 = Adc0
Rot_pwm2 = Adc3
Return

Timer1_pwm:
Gruen_pwm1 = Adc1
Gruen_pwm2 = Adc4
Return

Timer2_pwm:
Blau_pwm1 = Adc2
Blau_pwm2 = Adc5
Return
 
Hi,

ohne zum in deinen Code zu schauen,

kann es sein, dass du da logarithmische potis hast ?

Miss doch einfach mal mit einem Multimeter die Spannungen des Pottis.

Gruß,
Manuel
 
Bist Du sicher, daß getadc Dir 8-Bit-Ergebnisse liefert? (Der ADC hat ja eigentlich 10 Bit - man kann diese aber linksbündig in ein Byte schreiben, und die letzten beiden Bits weglassen...).
Aus der entsprechenden Config-Zeile geht das für mich nicht hervor (und die Onlinehilfe streikt bei mir grade).
Dann würde also eine 2-Byte-Var in ein Byte geschrieben werden - ob Bascom das kritisiert, oder einfach irgendwo abschneidet, weiß ich nicht.
 
Hallo!

Wie LotadaC schon angemerkt hat, Du versuchst einen 16Bit Wert in einen 8Bit Wert zu pressen.
Wenn Du das Poti langsam von Null nach Endanschlag drehst, wirst Du bemerken das 4mal von 0 -255 durchlaufen wird.
Entweder den ADC 8bittig auslesen oder sonst halt durch 4 teilen.

MfG
 
getadc scheint den 10-bit-Modus zu nehmen - right adjusted result. Ist also einem word zuzuweisen. das konn man dann durch 2x rechtschieben (=durch 4 teilen) in ein Byte überführen (üblicherweise addiert man hinterher noch das Carry zum runden).
 
Hi @ all,

also die Potis sind Trimmer mit jeweils 25 kOhm linear. Ich hatte gestern noch bevor jemand ein Kommentar schreiben konnte bei den ADC Werten von Byte auf Word umgestellt.
Somit wurden mir dann auf dem LCD auch die richtigen ADC Werte von 0 bis 1023 angezeigt. Dann habe ich die ADC Werte durch 4 geteilt. Rot_pwm1 = Adc0 / 4
und mit Locate 1 , 1 Lcd "" ; Rot_pwm1 auf dem LCD ausgeben lassen. Und schon wieder bekomme ich falsche Ergebnisse angezeigt. Durch das Teilen müsste aber rot_pwm1 doch nun als byte vorliegen
oder liege ich damit falsch?

Gruß Michael

Edit: Nun habe ich Folgendes getestet: Shift Adc0 , Right , 2 und nun wird der Wert auf dem LCD korrekt dargestellt.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)