Forum: Mikrocontroller und Digitale Elektronik 3x3 RGB LED - Multiplexing und Bit Angle Modulation


von Danny (Gast)


Lesenswert?

Ich habe mir zu Testzwecken eine 3x3 RGB LED Matrix auf einem Breadboard 
gebastelt. Die LEDs haben eine gemeinsame Kathode.

Für die Zeilen benutze ich pro Farbe ein Shift-Register (74HC595) und 
für die Spalten welche ich Multiplexen möchte laufen pro Spalte die 
gemeinsamen Kathoden zusammen und werden via NPN-Transistor (pro Spalte 
einen) mit einem GPIO meines Raspberry Pi verbunden.

Das reine ansprechen aller 9 LEDs in allen Farben ist sowei kein 
Problem.
Auch gezielt einzelne LEDs mittels BAM zu dimmen geht problemlos. Was 
ich aber noch nicht verstanden habe wie ich das ganze so gestalten kann, 
dass ich "Animationen" hinbekomme. Habe immer ein riesen durcheinander, 
dass die Abfolgen zu schnell sind oder die LEDs gewaltig flakern.
Bisher habe ich es mit Sleep (in Python time.sleep(x)) versucht und 
nicht mit interrupts. Soll ich das ändern?

Mein code sieht in etwa wie folgt aus (nicht optimiert mit Bit 
Operationen sondern als Prototyp mit String-Manipulation):
1
import RPi.GPIO as GPIO
2
import time
3
4
# Row  Pins
5
ROW0_PIN = 22
6
ROW1_PIN = 17
7
ROW2_PIN = 4
8
9
# RGB Pins
10
RED_PIN = 25
11
BLUE_PIN = 23
12
GREEN_PIN = 24
13
14
# I/O Pins
15
CLOCK_PIN = 27
16
LATCH_PIN = 18
17
RESET_PIN = 7
18
19
# GPIO Setup
20
GPIO.setmode(GPIO.BCM)
21
GPIO.setup(ROW0_PIN, GPIO.OUT)
22
GPIO.setup(ROW1_PIN, GPIO.OUT)
23
GPIO.setup(ROW2_PIN, GPIO.OUT)
24
GPIO.setup(RED_PIN, GPIO.OUT)
25
GPIO.setup(GREEN_PIN, GPIO.OUT)
26
GPIO.setup(BLUE_PIN, GPIO.OUT)
27
GPIO.setup(CLOCK_PIN, GPIO.OUT)
28
GPIO.setup(LATCH_PIN, GPIO.OUT)
29
GPIO.setup(RESET_PIN, GPIO.OUT)
30
31
# GPIO Initial
32
GPIO.output(ROW0_PIN, GPIO.LOW)
33
GPIO.output(ROW1_PIN, GPIO.LOW)
34
GPIO.output(ROW2_PIN, GPIO.LOW)
35
GPIO.output(RED_PIN, GPIO.LOW)
36
GPIO.output(GREEN_PIN, GPIO.LOW)
37
GPIO.output(BLUE_PIN, GPIO.LOW)
38
GPIO.output(CLOCK_PIN, GPIO.LOW)
39
GPIO.output(LATCH_PIN, GPIO.LOW)
40
GPIO.output(RESET_PIN, GPIO.HIGH)
41
42
# Send latch
43
def send_latch():
44
  GPIO.output(LATCH_PIN, GPIO.HIGH)
45
  GPIO.output(LATCH_PIN, GPIO.LOW)
46
47
# Send clock
48
def send_clock():
49
  GPIO.output(CLOCK_PIN, GPIO.HIGH)
50
  GPIO.output(CLOCK_PIN, GPIO.LOW)
51
52
def setRow(row):
53
  if row < 0:
54
    GPIO.output(ROW0_PIN, GPIO.LOW)
55
    GPIO.output(ROW1_PIN, GPIO.LOW)
56
    GPIO.output(ROW2_PIN, GPIO.LOW)
57
  if row == 0:
58
    GPIO.output(ROW0_PIN, GPIO.HIGH)
59
    GPIO.output(ROW1_PIN, GPIO.LOW)
60
    GPIO.output(ROW2_PIN, GPIO.LOW)
61
  elif row == 1:
62
    GPIO.output(ROW0_PIN, GPIO.LOW)
63
    GPIO.output(ROW1_PIN, GPIO.HIGH)
64
    GPIO.output(ROW2_PIN, GPIO.LOW)
65
  elif row == 2:
66
    GPIO.output(ROW0_PIN, GPIO.LOW)
67
    GPIO.output(ROW1_PIN, GPIO.LOW)
68
    GPIO.output(ROW2_PIN, GPIO.HIGH)      
69
70
def lowHigh(bit):
71
  if bit == '0':
72
    return GPIO.LOW
73
  else:
74
    return GPIO.HIGH
75
76
# Shift Register reset
77
def reset():
78
  GPIO.output(RESET_PIN, GPIO.LOW)
79
  GPIO.output(RESET_PIN, GPIO.HIGH)
80
  GPIO.output(LATCH_PIN, GPIO.HIGH)
81
  GPIO.output(LATCH_PIN, GPIO.LOW)
82
83
# Led Funktion
84
def led(x, y, red, green, blue):
85
86
  # Generiert das Bitmuster rückwärts mit führenden Nullen
87
  # Aus 254 wird 01111111
88
  # Aus  13 wird 11100000
89
  red_bit = bin(red)[2:].zfill(8)[::-1]
90
  green_bit = bin(green)[2:].zfill(8)[::-1]
91
  blue_bit = bin(blue)[2:].zfill(8)[::-1]
92
93
  # 1s / (3 Reihen mit 100Hz) / 255 Dimm-Stufen
94
  cycleTime = 1 / (3 * 100) / 255
95
  
96
  # Spalten 0 - 2
97
  for r in range(0, 3):
98
    # BAM Auflösung von 8 Bit (0-255)
99
    for i in range (0, 8):
100
      if y == r:
101
        if x == 2:
102
          red_shift = red_bit[i] + '00'
103
          green_shift = green_bit[i] + '00'
104
          blue_shift = blue_bit[i] + '00'
105
        elif x == 1:
106
          red_shift = '0' + red_bit[i] + '0'
107
          green_shift = '0' + green_bit[i] + '0'
108
          blue_shift = '0' + blue_bit[i] + '0'
109
        elif x == 0:
110
          red_shift = '00' + red_bit[i] 
111
          green_shift = '00' + green_bit[i]
112
          blue_shift = '00' + blue_bit[i]
113
      else:
114
          red_shift = '000'
115
          green_shift = '000'
116
          blue_shift = '000'
117
118
      # Anzeige ausschalten
119
      setRow(-1)
120
121
      # Für die 3 LEDs in der aktuellen Reihe das Muster anlegen
122
      for pinsInRow in range (0, 3):
123
        GPIO.output(RED_PIN, lowHigh(red_shift[pinsInRow]))
124
        GPIO.output(GREEN_PIN, lowHigh(green_shift[pinsInRow]))
125
        GPIO.output(BLUE_PIN, lowHigh(blue_shift[pinsInRow]))
126
        send_clock()
127
128
      # Muster für die aktuelle Reihe ausgeben
129
      send_latch()
130
131
      # Aktuelle Reihe einschalten
132
      setRow(r)
133
134
      # Die Wartezeit soll sich pro höherwertigem Bit erhöhen -> längere Leuchtzeit
135
      time.sleep(cycleTime * i)
136
137
reset()
138
139
try:
140
  while True:
141
142
    # Da brauche ich Hilfe
143
144
145
except KeyboardInterrupt:
146
  pass
147
148
GPIO.cleanup()

Wie muss ich z.B. die Main Methode gestalten, damit ich in der ersten 
Zeile Rot habe (LED 1: 100% LED 2: 75% LED 3: 50%)
in der zweiten Grün (LED 1: 100% LED 2: 75% LED 3: 50%)
und in der dritten Blau (LED 1: 100% LED 2: 75% LED 3: 50%)

Zuerst soll nur Zeile 1 (rot) leuchten, dann soll nach 1 Sekunde Zeile 2 
(grün) dazukommen und nach einer weiteren Sekunde soll noch Zeile 3 
dazukommem und gemeinsam leuchten. Danach wieder von vorne.

Bin da total irgend wie total auf dem Holzweg, bei all meinen Versuchen.

Ich erwarte keinen fertigen Lösungscode, sondern was ich umstellen muss 
resp. Pseudocode wie es vom Algorithnus her funktionieren sollte =)

Vielen Dank und Gruss
Danny

von Danny (Gast)


Lesenswert?

Bin nochmals auf einem Notizblock den gewünschten Ablauf durchgegangen 
und meinen Code entsprechend korrigiert. Nun funktioniert das 
Multiplexing und Dimmen (mit BAM) wie gewünscht =)

Thread hat sich somit erledigt.

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.