Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    LED rainbow effects

    Scheduled Pinned Locked Moved
    Gcode meta commands
    2
    3
    345
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • droftartsundefined
      droftarts administrators
      last edited by

      Recently I got a Mini12864 display, which has RGB Neopixels for the backlight and encoder wheel. I played around trying to set colours, but then thought it was a 'good' idea to get a rainbow effect working, for fun. I couldn't find much other RRF documentation on this, and eventually realised that using meta Gcode would make it easier, and helped as a simple project to start using meta Gcode.

      To start off with, this is using a Duet 3 Mini 5+. I started off on RRF 3.4, then moved to the RRF 3.5 beta. Some of the code below will work with older versions of RRF. The relevant bits of config.g to set up the screen and LEDs (yours may be different if using a different board/LED combo/RRF version):

      M918 P2 E-4 C70 R4             ; enable MKS Mini12864
      M150 X2 R60 U255 B0 P255 S3 F0 ; set LEDs for MKS Mini12864
      

      First, I found RGB colours for the seven colours of the rainbow. I put these in a spreadsheet, and generated the colours in between, to create a straight Gcode file that changed the colour. Note that on my screen, colours are ordered GRB rather than RGB, so U=red, R=green, B=blue in M150:

      M150 U148 R0 B211 S3 F0
      G4 P100
      M150 U141 R0 B203 S3 F0
      G4 P100
      M150 U133 R0 B195 S3 F0
      G4 P100
      M150 U126 R0 B187 S3 F0
      G4 P100
      M150 U119 R0 B179 S3 F0
      G4 P100
      M150 U112 R0 B171 S3 F0
      G4 P100
      M150 U104 R0 B162 S3 F0
      G4 P100
      M150 U97 R0 B154 S3 F0
      G4 P100
      M150 U90 R0 B146 S3 F0
      G4 P100
      M150 U82 R0 B138 S3 F0
      G4 P100
      M150 U75 R0 B130 S3 F0
      G4 P100
      M150 U68 R0 B143 S3 F0
      G4 P100
      M150 U60 R0 B155 S3 F0
      G4 P100
      M150 U53 R0 B168 S3 F0
      G4 P100
      M150 U45 R0 B180 S3 F0
      G4 P100
      M150 U38 R0 B193 S3 F0
      G4 P100
      M150 U30 R0 B205 S3 F0
      G4 P100
      M150 U23 R0 B218 S3 F0
      G4 P100
      M150 U15 R0 B230 S3 F0
      G4 P100
      M150 U8 R0 B243 S3 F0
      G4 P100
      M150 U0 R0 B255 S3 F0
      G4 P100
      M150 U0 R26 B230 S3 F0
      G4 P100
      M150 U0 R51 B204 S3 F0
      G4 P100
      M150 U0 R77 B179 S3 F0
      G4 P100
      M150 U0 R102 B153 S3 F0
      G4 P100
      M150 U0 R128 B128 S3 F0
      G4 P100
      M150 U0 R153 B102 S3 F0
      G4 P100
      M150 U0 R179 B77 S3 F0
      G4 P100
      M150 U0 R204 B51 S3 F0
      G4 P100
      M150 U0 R230 B26 S3 F0
      G4 P100
      M150 U0 R255 B0 S3 F0
      G4 P100
      M150 U26 R255 B0 S3 F0
      G4 P100
      M150 U51 R255 B0 S3 F0
      G4 P100
      M150 U77 R255 B0 S3 F0
      G4 P100
      M150 U102 R255 B0 S3 F0
      G4 P100
      M150 U128 R255 B0 S3 F0
      G4 P100
      M150 U153 R255 B0 S3 F0
      G4 P100
      M150 U179 R255 B0 S3 F0
      G4 P100
      M150 U204 R255 B0 S3 F0
      G4 P100
      M150 U230 R255 B0 S3 F0
      G4 P100
      M150 U255 R255 B0 S3 F0
      G4 P100
      M150 U255 R242 B0 S3 F0
      G4 P100
      M150 U255 R229 B0 S3 F0
      G4 P100
      M150 U255 R217 B0 S3 F0
      G4 P100
      M150 U255 R204 B0 S3 F0
      G4 P100
      M150 U255 R191 B0 S3 F0
      G4 P100
      M150 U255 R178 B0 S3 F0
      G4 P100
      M150 U255 R165 B0 S3 F0
      G4 P100
      M150 U255 R153 B0 S3 F0
      G4 P100
      M150 U255 R140 B0 S3 F0
      G4 P100
      M150 U255 R127 B0 S3 F0
      G4 P100
      M150 U255 R114 B0 S3 F0
      G4 P100
      M150 U255 R102 B0 S3 F0
      G4 P100
      M150 U255 R89 B0 S3 F0
      G4 P100
      M150 U255 R76 B0 S3 F0
      G4 P100
      M150 U255 R64 B0 S3 F0
      G4 P100
      M150 U255 R51 B0 S3 F0
      G4 P100
      M150 U255 R38 B0 S3 F0
      G4 P100
      M150 U255 R25 B0 S3 F0
      G4 P100
      M150 U255 R13 B0 S3 F0
      G4 P100
      M150 U255 R0 B0 S3 F0
      G4 P100
      

      This works, changing all three LEDs through the colours, and should work with RRF back to v3.3 (and possibly earlier depending on your LEDs) . But changing the colours is time-consuming, and it doesn't oscillate through the LEDs. Perhaps I could do better ...
      This is the eventual macro using meta Gcode, and should work with RRF 3.3 and later:

      var Red1 = 148
      var Red2 = 75
      var Red3 = 0
      var Red4 = 0
      var Red5 = 255
      var Red6 = 255
      var Red7 = 255
      
      var Green1 = 0
      var Green2 = 0
      var Green3 = 0
      var Green4 = 255
      var Green5 = 255
      var Green6 = 127
      var Green7 = 0
      
      var Blue1 = 211
      var Blue2 = 130
      var Blue3 = 255
      var Blue4 = 0
      var Blue5 = 0
      var Blue6 = 0
      var Blue7 = 0
      
      var Interpolation = 5
      
      while iterations<7
      
      	var RedA = (iterations = 0) ? var.Red1 : (iterations = 1) ? var.Red2 : (iterations = 2) ? var.Red3 : (iterations = 3) ? var.Red4 : (iterations = 4) ? var.Red5 : (iterations = 5) ? var.Red6 : (iterations = 6) ? var.Red7 : var.Red1
      	var GrnA = (iterations = 0) ? var.Green1 : (iterations = 1) ? var.Green2 : (iterations = 2) ? var.Green3 : (iterations = 3) ? var.Green4 : (iterations = 4) ? var.Green5 : (iterations = 5) ? var.Green6 : (iterations = 6) ? var.Green7 : var.Green1
      	var BluA = (iterations = 0) ? var.Blue1 : (iterations = 1) ? var.Blue2 : (iterations = 2) ? var.Blue3 : (iterations = 3) ? var.Blue4 : (iterations = 4) ? var.Blue5 : (iterations = 5) ? var.Blue6 : (iterations = 6) ? var.Blue7 : var.Blue1
      	
      	var RedB = (iterations = 0) ? var.Red2 : (iterations = 1) ? var.Red3 : (iterations = 2) ? var.Red4 : (iterations = 3) ? var.Red5 : (iterations = 4) ? var.Red6 : (iterations = 5) ? var.Red7 : (iterations = 6) ? var.Red1 : var.Red1
      	var GrnB = (iterations = 0) ? var.Green2 : (iterations = 1) ? var.Green3 : (iterations = 2) ? var.Green4 : (iterations = 3) ? var.Green5 : (iterations = 4) ? var.Green6 : (iterations = 5) ? var.Green7 : (iterations = 6) ? var.Green1 : var.Green1
      	var BluB = (iterations = 0) ? var.Blue2 : (iterations = 1) ? var.Blue3 : (iterations = 2) ? var.Blue4 : (iterations = 3) ? var.Blue5 : (iterations = 4) ? var.Blue6 : (iterations = 5) ? var.Blue7 : (iterations = 6) ? var.Blue1 : var.Blue1
      	
      	var RedC = (iterations = 0) ? var.Red3 : (iterations = 1) ? var.Red4 : (iterations = 2) ? var.Red5 : (iterations = 3) ? var.Red6 : (iterations = 4) ? var.Red7 : (iterations = 5) ? var.Red1 : (iterations = 6) ? var.Red2 : var.Red1
      	var GrnC = (iterations = 0) ? var.Green3 : (iterations = 1) ? var.Green4 : (iterations = 2) ? var.Green5 : (iterations = 3) ? var.Green6 : (iterations = 4) ? var.Green7 : (iterations = 5) ? var.Green1 : (iterations = 6) ? var.Green2 : var.Green1
      	var BluC = (iterations = 0) ? var.Blue3 : (iterations = 1) ? var.Blue4 : (iterations = 2) ? var.Blue5 : (iterations = 3) ? var.Blue6 : (iterations = 4) ? var.Blue7 : (iterations = 5) ? var.Blue1 : (iterations = 6) ? var.Blue2 : var.Blue1
      	
      	var RedD = (iterations = 0) ? var.Red4 : (iterations = 1) ? var.Red5 : (iterations = 2) ? var.Red6 : (iterations = 3) ? var.Red7 : (iterations = 4) ? var.Red1 : (iterations = 5) ? var.Red2 : (iterations = 6) ? var.Red3 : var.Red1
      	var GrnD = (iterations = 0) ? var.Green4 : (iterations = 1) ? var.Green5 : (iterations = 2) ? var.Green6 : (iterations = 3) ? var.Green7 : (iterations = 4) ? var.Green1 : (iterations = 5) ? var.Green2 : (iterations = 6) ? var.Green3 : var.Green1
      	var BluD = (iterations = 0) ? var.Blue4 : (iterations = 1) ? var.Blue5 : (iterations = 2) ? var.Blue6 : (iterations = 3) ? var.Blue7 : (iterations = 4) ? var.Blue1 : (iterations = 5) ? var.Blue2 : (iterations = 6) ? var.Blue3 : var.Blue1
      	
      	while var.Interpolation != iterations
      		
      		var r1 = floor(var.RedA + ((var.RedB - var.RedA) / var.Interpolation ) * iterations)
      		var g1 = floor(var.GrnA + ((var.GrnB - var.GrnA) / var.Interpolation ) * iterations)
      		var b1 = floor(var.BluA + ((var.BluB - var.BluA) / var.Interpolation ) * iterations)
      		
      		var r2 = floor(var.RedB + ((var.RedC - var.RedB) / var.Interpolation ) * iterations)
      		var g2 = floor(var.GrnB + ((var.GrnC - var.GrnB) / var.Interpolation ) * iterations)
      		var b2 = floor(var.BluB + ((var.BluC - var.BluB) / var.Interpolation ) * iterations)
      		
      		var r3 = floor(var.RedC + ((var.RedD - var.RedC) / var.Interpolation ) * iterations)
      		var g3 = floor(var.GrnC + ((var.GrnD - var.GrnC) / var.Interpolation ) * iterations)
      		var b3 = floor(var.BluC + ((var.BluD - var.BluC) / var.Interpolation ) * iterations)
      		
      		M150 U{var.r1} R{var.g1} B{var.b1} P255 S1 F1
      		M150 U{var.r2} R{var.g2} B{var.b2} P255 S1 F1
      		M150 U{var.r3} R{var.g3} B{var.b3} P255 S1 F0
      		G4 P50
      

      But with arrays now available in RRF 3.5, it can be improved ...

      var Red = {148,75,0,0,255,255,255}
      var Green = {0,0,0,255,255,127,0}
      var Blue = {211,130,255,0,0,0,0}
      
      var Colours = 7
      var Interpolation = 10
      
      while iterations < 21
      	
      	; First LED colour, this loops the colour array using mod
      	var LED1r = var.Red[mod(iterations,var.Colours)]
      	var LED1g = var.Green[mod(iterations,var.Colours)]
      	var LED1b = var.Blue[mod(iterations,var.Colours)]
      	
      	; Second LED colour
      	var LED2r = var.Red[mod(iterations+1,var.Colours)]
      	var LED2g = var.Green[mod(iterations+1,var.Colours)]
      	var LED2b = var.Blue[mod(iterations+1,var.Colours)]
      	
      	; Third LED colour
      	var LED3r = var.Red[mod(iterations+2,var.Colours)]
      	var LED3g = var.Green[mod(iterations+2,var.Colours)]
      	var LED3b = var.Blue[mod(iterations+2,var.Colours)]
      	
      	; For more LEDS, add LED with RGB offset from previous LED here.
      	
      	; Last colour, needed so the last LED has a colour to change to 
      	var LED4r = var.Red[mod(iterations+3,var.Colours)]
      	var LED4g = var.Green[mod(iterations+3,var.Colours)]
      	var LED4b = var.Blue[mod(iterations+3,var.Colours)]
      	
      	while var.Interpolation != iterations
      		
      		; set the first LED colour based on the iteration
      		var r1 = floor(var.LED1r + ((var.LED2r - var.LED1r) / var.Interpolation) * iterations)
      		var g1 = floor(var.LED1g + ((var.LED2g - var.LED1g) / var.Interpolation) * iterations)
      		var b1 = floor(var.LED1b + ((var.LED2b - var.LED1b) / var.Interpolation) * iterations)
      		
      		var r2 = floor(var.LED2r + ((var.LED3r - var.LED2r) / var.Interpolation) * iterations)
      		var g2 = floor(var.LED2g + ((var.LED3g - var.LED2g) / var.Interpolation) * iterations)
      		var b2 = floor(var.LED2b + ((var.LED3b - var.LED2b) / var.Interpolation) * iterations)
      		
      		var r3 = floor(var.LED3r + ((var.LED4r - var.LED3r) / var.Interpolation) * iterations)
      		var g3 = floor(var.LED3g + ((var.LED4g - var.LED3g) / var.Interpolation) * iterations)
      		var b3 = floor(var.LED3b + ((var.LED4b - var.LED3b) / var.Interpolation) * iterations)
      		
      		M150 U{var.r1} R{var.g1} B{var.b1} P255 S1 F1
      		M150 U{var.r2} R{var.g2} B{var.b2} P255 S1 F1
      		M150 U{var.r3} R{var.g3} B{var.b3} P255 S1 F0
      		G4 P50
      

      This is a little expansive, but relatively easy to read to understand what is going on. I'm sure it could be reduced in size and complexity, as I'm not much of a programmer, so feel free to suggest improvements. But I hope someone might find this useful, if only as a meta Gcode example!

      Ian

      Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

      droftartsundefined 1 Reply Last reply Reply Quote 5
      • droftartsundefined
        droftarts administrators @droftarts
        last edited by

        Thinking further about this, if the functionality of assigning individual array elements was added (currently not supported in 3.5.0beta1), all the interpolated values for R, G and B could be calculated up front and an array created for each first. Then a second loop could be used for the M150 command(s) that uses the RGB values from the calculated arrays, and offsets for different LEDs if different colours are required. This would simplify the code, but would mean more memory is taken up with the three long array variables. Is that 'bad' programming?!

        Ian

        Bed-slinger - Mini5+ WiFi/1LC | RRP Fisher v1 - D2 WiFi | Polargraph - D2 WiFi | TronXY X5S - 6HC/Roto | CNC router - 6HC | Tractus3D T1250 - D2 Eth

        OwenDundefined 1 Reply Last reply Reply Quote 0
        • OwenDundefined
          OwenD @droftarts
          last edited by

          @droftarts said in LED rainbow effects:

          This would simplify the code, but would mean more memory is taken up with the three long array variables. Is that 'bad' programming?!

          It's not "bad programming" to take advantage of available resources.
          Why have X amount of memory allocated/available and only ever use X/3 ?
          Unless it affects performance in some way , I say use whatever is available.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Unless otherwise noted, all forum content is licensed under CC-BY-SA