LED rainbow effects
-
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
-
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
-
@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.