Wie mache ich ein rotes Wabern mit WS2812-LED-Stripe

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Wie mache ich ein rotes Wabern mit WS2812-LED-Stripe

      Hallo Leute,
      ich benötige für ein Halloweengimmick eine Hintergreundbeleuchtung mit einem WS2812-Streifen die um ein Bild herum ein waberndes rotes Licht erzeugen soll. Aber nicht gleichmässig sondern halt ungleichmässig. Ich hab es schon mal mit tschoeatsch`s Laterne mit nur einem Kanal probiert, aber das ist halt eher eine Flamme, also zum Ende hin auslaufend. Ich bräucht es aber gleichmässig. Meine Erfolge bisher sind mehr wie dürftig, lediglich mein Ein- und Ausfaden klappt so halbwegs ansehnlich.
      Hat jemand von euch eine Idee wie ich da am besten vorgehen kann? Für einen Tipp wäre ich dankbar.

      Joachim
    • Bis halloween ist ja noch bisschen Zeit. Wieviele Leds verwendest du? Wabernd wäre, wenn an zufälligen Stellen das Rot stärker und wieder schwächer wird und dieser Stelle erst zu einem anderen, zufälligen, Zeitpunkt wieder aufglimmt? Und wieviele Leds sind von so einer 'Zelle' betroffen?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo, es wird ein beleuchteter Bilderrahmen, also ich rechne mit so zwei Meter mit jeweils 60Leds/m also 120 Leds. Und ja, so wie du es beschreibst soll es sein. Mit einer gewissen Grundhelligkeit. Und an mehreren Stellen um das Bild herum. Wieviel Leds pro Zelle hab ich mir noch nicht so überlegt. Das müsste ich mit anschauen. Aber so >4 Leds sollten es schon sein.

      Ich habe mir jetzt mal eine 32-Werte Helligkeitstabelle generiert, damit ich über den Bereich eine gleichmässige Helligkeitsänderung bekomme. Dann dachte ich mir Zellen mit x Leds zu generieren und die dann irgendwie in die Kette ein- und auszufaden.
      Aber wie?
    • Mal eine Idee: ein array, zweidimensional. Etwa so array(Index, 6). Die Größe des Index entspricht der Anzahl der Zellen. Bei 120Leds und 3 Leds pro Zelle vielleicht dann 20.
      array(x,1) wäre Lednummer
      Array(x,2) wäre Zielhelligkeit
      (x,3) wäre Helligkeit
      (x,4) wäre Richtung
      (x,5) wäre Verzögerung
      (x,6) wäre Zähler.
      Jetzt gibt es eine Schleife, for index=1 to 20 und in der Schleife wird dann geprüft: steht eine gültige Lednummer drin,
      wenn nein,
      dann würfeln und da rein schreiben
      Zielhelligkeit würfeln und rein schreiben
      akt_helligkeit=Grundhelligkeit
      Richtung=1
      Verzögerung würfeln und rein schreiben
      Zähler=0
      wenn eine gültige Lednummer drin steht, dann wird's aufwändiger. In Abhängigkeit der Richtung wird bis zur Zielhelligkeit die Helligkeit incrementiert (Richtung=1), bzw decrementiert (Richtung=0), das aber auch nur, wenn der Zähler = Verzögerung ist. Der Zähler wird bei jedem Durchlauf der Schleife incr, und bei Erreichen von Verzögerung auf 0 gesetzt.
      Wird die Zielhelligkeit erreicht, wird die Richtung auf 0 gesetzt.
      Erreicht Helligkeit eine gewünschte Grundhelligkeit, dann wird die Lednummer auf eine ungültige Nummer gesetzt, damit beim nächsten Durchlauf der Schleife wieder gewürfelt wird und an einer neuen Stelle eine Zelle entsteht.
      Die Verzögerung sorgt für verschieden schnelles dimmen.
      Die Zellenbreite kann man jetzt beim Schreiben des stripes beeinflussen. ZB nimmt man die Lednummer und setzt da die Helligkeit gemäß array und die Led davor und dahinter bekommen die halbe Helligkeit zugewiesen.
      Kannst du damit was anfangen?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Die Daten für die Strips sollten natürlich in einem Array vorgehalten werden.
      Am besten natürlich so, dass man sie einfach 1:1 alle auf einmal raus schieben kann.
      Das kann man ja per Timer regelmäßig machen.

      Im Prinzip muss man nur die LED's (Array-Zellen) manipulieren, um das Wabern zu erhalten.

      Mein Vorschlag wäre, einen LED-Bereich (Zelle nennt ihr das) mittels RND festzulegen.
      Damit das Wabern nicht immer an der gleichen stelle ist.

      Dann kann man mit RND einen Peakwert (maximale Helligkeit) ermitteln, der dann in den Bereich eingebracht wird.
      Per Timer wird dieser Bereich immer wieder etwas dekrementiert bis zur Grundhelligkeit.

      Das Prinzip entspricht quasi einer Audio Aussteuerungsanzeige (Equalizer).

      Will man mehrere Stellen Wabern haben, kann man auch per RDN 2 Bereiche ermitteln, an denen das Wabern statt finden soll.

      Wenn man die Bereiche per RND wechselt, das Wabern (Peakwert) per RDN ermittelt und das immer Abwechselnd, könnte da einen Netten Effekt geben.
    • @tschoeatsch
      So in derArt hab ich es auch gedacht. Da werde ich morgen mal probieren. Im Moment aber erst mal mit einheitlicher Zeit. Hier mal grober Entwurf. Ist noch etwas Pseudocode, ist am Tablet entstanden. Dachte nur es geht einfacher.

      Source Code

      1. Min_hell=5
      2. 'Array
      3. ' Led (Basisled)
      4. ' Breite (zellenbreite in Leds, zweimal für links und rechts)
      5. ' zielhelligkeit (32 werte aus gabelle)
      6. ' Schritte (zählen auf eins runter)
      7. dim glow(20,4) as byte
      8. ' Array leer setzen
      9. For count=1 to 20
      10. Glow(count,1)=&hff ' als frei markieren
      11. next count
      12. Fade_in ' auf Grundhelligkeit einfaden
      13. Do
      14. 'Godown. Alle LEDs dunkler machen
      15. For count=0 to Num_leds
      16. Farbe(1)=rb_getcolor(count)
      17. If red>min_hell Then
      18. decr red
      19. rb_setcolor(Count,farbe(1)
      20. End if
      21. Next Count
      22. ' Hier gucken ob es ein neues glow gibt
      23. Newglow=rnd(10) '10 versuche bis neues glow, ggf ändern
      24. if newglow=1 then ' wenn neu
      25. ' leeren platz suchen
      26. For newglow=1 to 20
      27. If glow(newglow,1)=&hff then
      28. glow(newglow,1)=rnd(num_leds) ' welche led
      29. glow(newglow,2)=rnd(3)+1 ' wie breit, min 1
      30. glow(newglow,3)=rnd(33)+min_hell
      31. if glow(newglow,3)>32 then glow(newglow,3)=32
      32. glow(newglow,4)=rnd(30)+10
      33. exit for
      34. End if
      35. Next newglow
      36. End if
      37. ' hier werden die glows aktualisiert
      38. For newglow=1 to 20
      39. Led=glow(newglow,1)
      40. If led<>&hff then
      41. rot = glow(newglow,3)/glow(newglow,4) helligkeit/Schritte
      42. setcolor led, color(1)
      43. for h=1 to breite
      44. Red=red/2
      45. l=led-1:if l=&hff then l=num_leds
      46. setcolor led-1, color(1)
      47. l=led+1:if l>num_leds then l=0
      48. setcolor led+1, color(1)
      49. next h
      50. Decr schritt
      51. If schritt=0 then Led=&hff ' deaktivieren
      52. End if
      53. ' und raus damit
      54. Rb_send
      55. 'Portpin beendet da Spiel
      56. If pin=low then exit do
      57. ' kurz warten und dann weiter
      58. Waitms 50
      59. Loop
      60. 'LEDs ausfaden
      61. fade_out
      Display All
      @'Mitch64

      Das war meine erste Idee. So hab ich es mal für ein KnightRiderlicht gemacht. Aber du lädst dieLEDs direkt auf, es soll aber einfaden.
    • Wenn ich deinen code richtig verstehe, dann 'zündest' du eine Zelle, die dann langsam ausglimmt? Keine schlechte Idee, würde ich aber nicht als wabern bezeichnen. Wabern ist für mich ein langsamer, gleitender Effekt, daher mein Gedanke mit hoch- und runterdimmen. Das ist aber jetzt keine Kritik! Vielleicht komm' ich morgen mal zu einem code-Versuch, am Ende ist meine Idee ja optisch lasch. Einen Nachteil hat sie auf jeden Fall, wenn 2 Zellen nah beieinander stehen. Es werden ja die Helligkeiten der Leds einer Zelle aus der mittleren errechnet. Da kann dann der Rand einer abdimmenden Zelle, den Rand einer aufdimmenden Zelle runter ziehen und so eine optische Kante erzeugen. Ich hab' jetzt keinen Plan, wie man das verhindern könnte.

      Nachtrag: das Zünden hat schon was, man könnte das auch mit einem Gelb-/Blauanteil im erstem Moment als 'Blitz' erscheinen lassen, der dann mit rot ausglimmt. Dann müsste man nur die Stelle und die Breite würfeln, diese Initialwerte eintragen und dann mit der Zeit runter zählen. Die Gelb/blauanteile halt entsprechend rasch.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      The post was edited 2 times, last by tschoeatsch ().

    • nein, das ist anders gedacht. Und zwar mehr odr weniger daswas dir vorschwebte.
      Der erste Block fadet alle LEDs immer Richtung minimaler helligket.
      Im zweiten Block werden ggf. Neue Glows erzeugt.
      Und im dritten Block werden die einzelnen Glows mit der entsprechenden Breite in die Leds eingefadet. Ich teile ja die Helligkeit durch die Schritte. Also am Anfang grosser Teiler=geringe Helligkeit, am schluss 1=vole helligket. Und die Zellen rundum kriegen jeweils die Hälfte der Zentralled-Helligkeit. Und wenn sie voll ingefadet sind wird der Gloweintrag gelöscht. Dann greift der erste Block und fadet ihn aus.
      Es ist also so wie du vorgeschlagen hast nur mit dem Untrschied dass ich das Ausfaden immer mache und beim Einfaden die Werte überschreibe.
      Die Breite und Helligkeitswerte werde ich ausprobieren, mal sehen.
    • Ich würde einen Sinus berechnen, die Werte in einen entsprechend nutzbaren Wertebereich transformieren und diese Werte statisch ablegen.
      Diese Werte dann einfach in WS reinschieben und das Ganze zeitlich gesteuert mit verschobenem Anfang der Werte aus dem Wertebereich wiederholen.

      Edit:
      Allerdings gibt es ein Problem:
      Die Helligkeit einer LED ist nicht analog der Schritte z.B. von 0-10 und 200-210
      Code first, think later - Natural programmer :D
    • New

      So, ich hab mal das Programm geschrieben und getestet. Soweit so gut, aber jetzt mein Riesenproblem. Ich habe diverse Änderungen zur Berechnung der Zwischenwerte geändert und seitdem bleibt das Programm einfach mittendrin stehen. Und zwar reproduzierbar an der gleichen Stelle. Ich nutzte eine Nano-Klon mit einem 328er. Ich finde keinen Fehler bei der Sache und bin schon am Verzweifeln.
      Ich hänge daas Programm mal an.
      Bei der Printausgabe erscheint:

      10 25 30 1 0
      10 25 30 1 0.83333325
      10 25 30 2 1.666666505
      10 25 30 3 2.5
      wobei die erste Zahl die LED ist, die zweite die Maximale Helligkeit, dann die Anzahl der Schritte und der aktuelle Schritt
      und dann steht das Programm bis zum Reset.

      BASCOM Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000
      3. $hwstack = 32
      4. $swstack = 256
      5. $framesize = 128
      6. Config Base = 0
      7. '*************************************************************
      8. 'user-Einstellungen
      9. Const Num_leds = 50
      10. '*************************************************************
      11. Config Rainbow = 1 , Rb0_len = Num_leds , Rb0_port = Portd , Rb0_pin = 2
      12. Rb_selectchannel 0
      13. Dim Count As Word , Count1 As Word , Newglow As Byte
      14. Dim Zelle As Byte , Zl As Byte
      15. Dim Led As Byte
      16. Dim Color(3) As Byte
      17. Red Alias Color(_base)
      18. Green Alias Color(_base + 1)
      19. Blue Alias Color(_base + 2)
      20. Dim Red_array(num_leds) As Byte
      21. Dim Temp As Single
      22. Const Min_hell = 2
      23. Const Max_hell = 32
      24. ' Array
      25. ' 0 Led (Basisled)
      26. ' 1 Breite (zellenbreite in Leds, zweimal für links und rechts)
      27. ' 2 zielhelligkeit (32 werte aus Tabelle)
      28. ' 3 Schritte
      29. ' 4 Aktueller Schritt
      30. Dim Glow(20 , 5) As Byte
      31. ' Array leer setzen
      32. For Count = 0 To 19
      33. Glow(count , 0) = &HFF ' als frei markieren
      34. Next Count
      35. Rb_clearstripe
      36. '########################################
      37. '###### FadeIn
      38. '########################################
      39. Green = 0 : Blue = 0
      40. For Count = 0 To Min_hell
      41. Red = Lookup(count , Helligkeit)
      42. Rb_fill Color(0)
      43. ' Waitms 100
      44. Next Count
      45. For Count = 0 To Num_leds
      46. Red_array(count) = Min_hell
      47. Next Count
      48. Newglow = 0
      49. Glow(newglow , 0) = 10 ' welche led
      50. Glow(newglow , 1) = 4 ' wie breit, min 1
      51. Glow(newglow , 2) = 25
      52. Glow(newglow , 3) = 30
      53. Glow(newglow , 4) = 1
      54. Do
      55. 'Godown, alle LEDs dunkler machen
      56. For Count = 0 To Num_leds
      57. If Red_array(count) > Min_hell Then Decr Red_array(count)
      58. Next Count
      59. ' Hier gucken ob es ein neues glow gibt
      60. Newglow = Rnd(5) '10 versuche bis neues glow, ggf ändern
      61. If Newglow = 1 Then ' wenn neu
      62. ' leeren platz suchen
      63. For Newglow = 0 to 19
      64. If Glow(newglow , 0) = &HFF Then
      65. Glow(newglow , 0) = Rnd(num_leds) ' welche led
      66. Glow(newglow , 1) = Rnd(10) + 1 ' wie breit, min 1
      67. Glow(newglow , 2) = 25 'Rnd(max_hell + 1) + Min_hell ' wie hell
      68. If Glow(newglow , 2) > Max_hell Then Glow(newglow , 2) = Max_hell
      69. Glow(newglow , 3) = 30 'Rnd(20) + 20 ' wie lang
      70. Glow(newglow , 4) = 1 ' Beginn
      71. Exit For
      72. End If
      73. Next Newglow
      74. End If
      75. ' hier werden die glows aktualisiert
      76. For Newglow = 0 To 19
      77. Led = Glow(newglow , 0)
      78. If Led <> &HFF Then
      79. Print Led ; " ";
      80. Temp = Glow(newglow , 2) * Glow(newglow , 4) ' Helligkeit im Verhältnis
      81. Temp = Temp / Glow(newglow , 3) ' Schritte
      82. Red = Int(temp)
      83. Print Glow(newglow , 2) ; " " ; Glow(newglow , 3) ; " " ; Glow(newglow , 4) ; " " ; Temp ; " " ; Red
      84. If Red > Min_hell Then Red_array(led) = Red
      85. For Zelle = 1 To Glow(newglow , 1)
      86. If Red > 2 Then Red = Red - 2 Else Red = 0
      87. If Red > Min_hell Then
      88. Zl = Led - Zelle : If Zl = &HFF Then Zl = Num_leds ' Aufpassen
      89. Red_array(zl) = Red
      90. Zl = Led + Zelle : If Zl > Num_leds Then Zl = 0
      91. Red_array(zl) = Red
      92. End If
      93. Next Zelle
      94. Incr Glow(newglow , 4)
      95. If Glow(newglow , 4) > Glow(newglow , 3) Then Glow(newglow , 0) = &HFF ' deaktivieren
      96. End If
      97. Next Newglow
      98. ' und raus damit
      99. Green = 0 : Blue = 0
      100. For Count = 0 To Num_leds
      101. Red = Lookup(red_array(count) , Helligkeit)
      102. Rb_setcolor Count , Color(0)
      103. Next Count
      104. Rb_send
      105. 'Portpin beendet da Spiel`
      106. ' If Pin = Low Then Exit Do
      107. ' kurz warten und dann weiter
      108. Waitms 100
      109. Loop
      110. '########################################
      111. '###### FadeOut
      112. '########################################
      113. Red = 1 : Green = 1 : Blue = 1
      114. For Count = 1 To 255
      115. For Count1 = 0 To Num_leds
      116. Rb_subcolor Count1 , Color(1)
      117. Next Count1
      118. Rb_send
      119. Next Count
      120. End
      121. Helligkeit:
      122. Data 0 , 1 , 3 , 5 , 7 , 9 , 11 , 13
      123. Data 15 , 17 , 19 , 21 , 23 , 25 , 27 , 29
      124. Data 31 , 33 , 35 , 38 , 48 , 54 , 64 , 76
      125. Data 91 , 108 , 128 , 152 , 182 , 212 , 230 , 255
      Display All

      Ich hoffe ihr könnt mir weiterhelfen.
      Joachim
    • New

      Hi Joachim,

      Du hast zu Beginn geschrieben, dass Du es mit dem Flammencode versucht hattest, der aber nicht geeignet war, weil er am Ende ausläuft.
      Wäre dann dieser Effekt etwas für Dich?



      Ich hab mir damals den Code vom Ersteller des Videos angesehen (war C oder sonst was), hat aber gereicht, um ihn nach Bascom zu übersetzen. Vielleicht wäre das auch etwas für Dich?

      BASCOM Source Code

      1. 'Gleichmäßiges Feuer V1 WS2812-Leds
      2. 'Bascom Version 2.0.8.0 Beta
      3. '$sim
      4. $regfile = "attiny85.dat"
      5. $crystal = 8000000
      6. $hwstack = 32
      7. $swstack = 10
      8. $framesize = 40
      9. Const Num_leds = 30
      10. Const Num_leds_1 = Num_leds - 1
      11. Config Rainbow = 1 , Rb0_len = Num_leds , Rb0_port = Portb , Rb0_pin = 1
      12. Rb_selectchannel 0
      13. Dim Farbe(3) As Byte
      14. Rot Alias Farbe(_base)
      15. Gruen Alias Farbe(_base + 1)
      16. Blau Alias Farbe(_base + 2)
      17. Dim N As Byte
      18. Dim Flackern As Integer
      19. Dim R As Integer
      20. Dim G As Integer
      21. Dim B As Integer
      22. Dim Rot_1 As Integer
      23. Dim Gruen_1 As Integer
      24. Dim Blau_1 As Integer
      25. Dim Speed As Byte
      26. Do
      27. R = 255
      28. G = R - 160
      29. B = 15
      30. For N = 0 To Num_leds_1
      31. Flackern = Rnd(50)
      32. Rot_1 = R - Flackern
      33. Gruen_1 = G - Flackern
      34. Blau_1 = B - Flackern
      35. If Rot_1 < 0 Then Rot_1 = 0
      36. If Gruen_1 < 0 Then Gruen_1 = 0
      37. If Blau_1 < 0 Then Blau_1 = 0
      38. Rot = Rot_1
      39. Gruen = Gruen_1
      40. Blau = Blau_1
      41. Rb_setcolor N , Farbe()
      42. Next N
      43. Rb_send
      44. Speed = Rnd(80)
      45. Speed = Speed + 100
      46. Waitms Speed
      47. Loop
      48. End
      Display All



      Nette Grüße
      Robert
    • New

      @'R2D2 Bastler
      Das schau ich mir mal an. Jetzt wo meins läuft war ja klar, dass ich was fertiges finde :D


      Den Fehler in meinem Programm hab ich gefunden. Ich Vollidiot hab auf Base 0 umgestellt aber die Schleifen zu weit laufen lassen X( . Jetzt sieht es schon sehr gut aus.
      Code mal anbei.
      Files
      • Fade.bas

        (4.88 kB, downloaded 9 times, last: )

      The post was edited 1 time, last by BASBAER ().