Temperature controlled LED display
-
This is what I've got to change my the colour of my 60 neopixels strip, the first and last ones show blue or red when when when the bed and heater is above 50C and change the brightness of the chamber.
; daemeon.g ; Adafruit #1426 8 led neopixel M150 X3 if heat.heaters[1].current > 50 ; temp M150 R255 Y5 S1 F1 ; Red 255 Y =Bightness 0-31 S = Number M150 W255 Y5 S19 F1 M150 W255 Y20 S20 F1 elif heat.heaters[1].current <= 50 M150 B255 Y5 S1 F1 M150 W255 Y5 S19 F1 M150 W255 Y5 S20 F1 if heat.heaters[0].current > 50 ; temp M150 W255 Y2 S19 F1 M150 R255 Y5 S1 F0 elif heat.heaters[0].current <= 50 M150 W255 Y2 S19 F1 M150 B255 Y5 S1 F0
-
@rushmere3d said in Temperature controlled LED display:
I would like the groups of 5 LEDs to change colour based on the tools temp, so say <30°C = Green, temps between 31-80°C = Orange and temps >81°C = Red
Something like this would probably work.
I don't have LED strips to test it on, so the M150 commands may need work.
You could call this from daemon.g which runs every 10 seconds by default.What it SHOULD do is loop through each tool and for each tool get the highest heater temperature of the heaters assigned to that tool.
Usually there's only one heater per tool, but may as well future proof.;set_led_by_temp.gcode ; set neopixels based on heater temp ; define the LED (probably should be in config.g) M150 X1 Q3000000 ; set LED type to NeoPixel and set SPI frequency to 3MHz ; adjust these variables temps to suit var lowHeat = 45 var medHeat = 60 var highHeat = 80 var pixelsPerTool = 5 ; create other needed variables var thisHeater= 0 var thisHeaterTemp = 0 var upperTemp = 0 var thisTool= 0 var F=0 ; ; gather the temperatures while iterations < #tools ; loop through the tools set var.thisTool = iterations set var.upperTemp = 0 ; reset the upper temp while iterations < #tools[var.thisTool].heaters ; loop through the heaters on each tool and get max temp set var.thisHeater = tools[var.thisTool].heaters[iterations] set var.thisHeaterTemp = heat.heaters[var.thisHeater].current if var.thisHeaterTemp > var.upperTemp set var.upperTemp = var.thisHeaterTemp ; determine if there will be more commands in this loop if iterations = #tools - 1 set var.F = 0 else set var.F = 1 ; Set the group of LEDs based on the temperature if var.upperTemp >= var.highHeat M150 R255 P255 S{var.pixelsPerTool} F{var.F} ; set pixels to red echo "Tool ", iterations , "set to red" elif var.upperTemp >= var.medHeat M150 R255 U128 P255 S{var.pixelsPerTool} F{var.F} ; set pixels to orange echo "Tool ", iterations , "set to orange" else M150 U128 P255 S{var.pixelsPerTool} F{var.F} ; set pixels to green echo "Tool ", iterations , "set to green"
-
@owend Thanks!!! This worked perfectly
-
I really like all these little 'tweaks' people do to their machines!
I'm going to learn from this to control a series of neopixel LEDs to change colour depending on the spindle speed for my CNC machine, and also have 3-colour LEDs to show my machine in Safe (Green: switched on but not in use/file not loaded), Pause (Orange) and Red (Running a project).
It's all pointless, of course, because I can usually tell when the CNC is working (the noise is a good clue!) but it will help me to learn about coding!
-
I decided to do some more work on this as a bit of a project.
I don't have any LED strips to test with as yet, but I believe this will work.I have created two macros.
One that does all the hard work. (set_led_by_temp.gcode)
It will gradually change colours based on the values you set for LOW, MEDIUM & HIGH heat.
Above or below this values it will set a constant colour.
The brightness may also be scaled depending on how close it is to the next break point.The other macro would be called from your slicer start code after setting the nozzle temp.
It will keep calling the first macro until the target temp is reached and then will set the LED's to white.
You could call it at the end of the print by creating a similar macro waiting for cool down.Macro to put in start code
; set_LED_while_heating.g ; Parameters can be passed for Tool number and target temp ; S = target temperature ; T = Tool number ; D = delay between checks ; example in Prusa slicer start code ; #### ; M568 P[current_extruder] R{"{heat.coldExtrudeTemperature+5}"} S[first_layer_temperature_0] A2 ; M98 P"set_LED_while_heating.gcode" S[first_layer_temperature_0] T[current_extruder] D3 ; M116 ; ### var toolNumber = 0 var targetTemp = 120 var delay = 3 var heaterNumber = tools[var.toolNumber].heaters[0] if exists(param.T) set var.toolNumber = param.T if exists(param.S) set var.targetTemp = param.S if exists(param.D) set var.delay = param.D while heat.heaters[var.heaterNumber].current < var.targetTemp M98 P"set_led_by_temp.gcode" G4 S{var.delay} ; done heating, so set to white M150 R255 U255 B255 W255 P255 F0 ; set pixels
Main macro
; set_led_by_temp.gcode ; This macro sets neopixels based on tool heater temp ; It should be called from daemon.g to achieve continual updates ; or by another macro with a loop if you only want to change colours during heatup ;example macro called from your slicer start code before after temps, but before M116 ; ##### ;while heat.heaters[1].current < 120 ; M98 P"set_led_by_temp.gcode" ; G4 S3 ; done heating, so set to white ;M150 R255 U255 B255 W255 P255 F0 ; set pixels ; ####### ; LED strip pixel count must equal number of tools * pixels per tool ; For multiple tools the neopixels must be daisy chained or a continuos strip ; The colour will gradually scale from one to the next. ; define the LED (should be in config.g as the value is remembered between calls) ;M150 X2 Q3000000 ; set LED type to NeoPixel bit banged type and set SPI frequency to 3MHz var RGBW = false ; set to true if LED is RGBW type, oherwise set to false var logging = true ; set to true if you want echos to appear in console to help see what the values are. Otherwise set false ; adjust these variable temps to suit requirements. var lowTemp = 30 var medTemp = 70 var highTemp = 120 ; brightness will be scaled between lowBrightness and highBrightness according to how close it is the max for range ; eg. between low temp and med temp ; once over high temp it will scale between high temp and max heater temp as set in config.g ; to not scale brightness, set both values the same var lowBrightness = 100 var highBrightness = 255 ; number of pixels on the strip that are assigned to each tool e.g first five are tool 1, second 5 are tool 2 etc ; if only one tool is used, set to total number of led's on strip var pixelsPerTool = 5 ; Common RGB colours (R,G,B) ; RED - 255,0,0 ; YELLOW - 255,255,0 ; ORANGE - 255,165,0 ; BLUE - 0,0,255 ; LIME - 0,255,0 ; GREEN - 0,128,0 ; MAGENTA - 255,0,255 ; WHITE - 255,255,255 ; OFF - 0,0,0 ;adjust values following to achieve desired colors for each range ; this will be so much easier when we have arrays ;-) ; all values must be integers between 0 & 255 ; high temp values (anything over high temp will be set to this) var highRed = 255 var highGreen = 12 var highBlue = 40 var highWhite = 0 ; only used on RGBW type ;medium temp values var midRed = 200 var midGreen = 128 var midBlue = 20 var midWhite = 40 ; only used on RGBW type ;low temp values var lowRed = 0 var lowGreen = 255 var lowBlue = 0 var lowWhite = 60 ; only used on RGBW type ; cold temp values (anything under low temp will be set to this) var coldRed = 0 var coldGreen = 0 var coldBlue = 255 var coldWhite = 0 ; only used on RGBW type ; ############################# SHOULD NOT NEED TO EDIT PAST HERE ################################ ; create other needed variables var thisHeater= 0 var thisHeaterTemp = 0 var upperTemp = 0 var thisTool= 0 var F=0 var maxTemp = 0 var brightScale = 0 var redValue = 0 var greenValue = 0 var blueValue = 0 var whiteValue = 0 var setBrightness = 0 var redScale= 0 var greenScale = 0 var blueScale = 0 var whiteScale = 0 var lowValue = 0 var highValue = 0 ; sanity checks if (var.lowBrightness < 0) || (var.highBrightness > 255) || (var.highBrightness < var.lowBrightness) echo "Invalid brightness settings. Must be between 0 & 255. High must be > than low. Setting to defaults (Low 100, high 255)" set var.lowBrightness = 100 set var.highBrightness = 255 if (var.lowTemp <= 0) || (var.medTemp <= var.lowTemp) || (var.highTemp <= var.medTemp) echo "Invalid temp range setings - resetting to defaults (low=50, medium=130,high=180)" set var.lowTemp = 50 set var.medTemp = 130 set var.highTemp = 180 if (var.logging != true) && (var.logging != false) echo "Invalid logging value- must be true or false" set var.logging = false ; gather the tool temperatures while iterations < #tools ; loop through the tools set var.thisTool = iterations set var.upperTemp = 0 ; reset the upper temp set var.maxTemp = 0 ; reset the max temp set var.lowValue = 0 set var.highValue = 0 while iterations < #tools[var.thisTool].heaters ; loop through the heaters on each tool and get max temp if var.logging = true echo "Checking tool", var.thisTool, "heater", iterations set var.thisHeater = tools[var.thisTool].heaters[iterations] set var.thisHeaterTemp = heat.heaters[var.thisHeater].current if var.logging = true echo "Heater", iterations, ". Temp =", var.thisHeaterTemp if var.thisHeaterTemp > var.upperTemp set var.upperTemp = var.thisHeaterTemp set var.maxTemp = heat.heaters[var.thisHeater].max if var.logging = true echo "Max temp of heaters is" , var.upperTemp ; determine if there will be more commands in this loop if iterations = #tools - 1 set var.F = 0 else set var.F = 1 ; Set the group of LEDs based on the temperature ; high temp range so just set to high temp colour values, bt scale brightness up to max heater temp if var.upperTemp >= var.highTemp set var.brightScale = (var.highBrightness - var.lowBrightness) / (var.maxTemp - var.highTemp) set var.setBrightness = floor((var.brightScale * (var.thisHeaterTemp - var.highTemp)) + 0.5) + var.lowBrightness ; set var.redValue = var.highRed ; set var.blueValue = var.highBlue set var.greenValue = var.highGreen set var.whiteValue = var.highWhite if var.logging = true echo "Temp is > ", var.highTemp echo "RGB(W) values set to -" , var.redValue, var.greenValue, var.blueValue, var.whiteValue echo "Brightness set to", var.setBrightness ; medium range - colours will be scaled between lowtemp and medium tempas will brightness elif var.upperTemp >= var.medTemp set var.brightScale = (var.highBrightness - var.lowBrightness) / (var.highTemp - var.medTemp) set var.setBrightness = floor(var.brightScale * (var.thisHeaterTemp - var.medTemp) + 0.5) + var.lowBrightness ; set var.lowValue = min(var.highRed,var.midRed) set var.highValue = max(var.highRed,var.midRed) set var.redScale = (var.highValue - var.lowValue) / (var.highTemp - var.medTemp) set var.lowValue = min(var.highGreen,var.midGreen) set var.highValue = max(var.highGreen,var.midGreen) set var.greenScale = (var.highValue - var.lowValue) / (var.highTemp - var.medTemp) set var.lowValue = min(var.highBlue,var.midBlue) set var.highValue = max(var.highBlue,var.midBlue) set var.blueScale = (var.highValue - var.lowValue) / (var.highTemp - var.medTemp) set var.lowValue = min(var.highWhite,var.midWhite) set var.highValue = max(var.highWhite,var.midWhite) set var.whiteScale = (var.highValue - var.lowValue) / (var.highTemp - var.medTemp) if var.midRed < var.highRed set var.redValue = floor((var.redScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) + var.midRed else set var.redValue = var.midRed - floor((var.redScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) if var.midGreen < var.highGreen set var.greenValue = floor((var.greenScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) + var.midGreen else set var.greenValue = var.midGreen - floor((var.greenScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) if var.midBlue < var.highBlue set var.blueValue = floor((var.blueScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) + var.midBlue else set var.blueValue = var.midBlue - floor((var.blueScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) if var.midWhite < var.highWhite set var.whiteValue = floor((var.whiteScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) + var.midWhite else set var.whiteValue = var.midWhite - floor((var.blueScale * (var.thisHeaterTemp - var.medTemp)) + 0.5) if var.logging = true echo "Temp is > ", var.medTemp, "but < ", var.highTemp echo "RGB(W) values set to -" , var.redValue, var.greenValue, var.blueValue, var.whiteValue echo "Brightness set to", var.setBrightness ; low temp range - colours will be scaled between cold tempand medium temp range, as will brightness elif var.upperTemp >= var.lowTemp set var.brightScale = (var.highBrightness - var.lowBrightness) / (var.medTemp - var.lowTemp) set var.setBrightness = floor(var.brightScale * (var.thisHeaterTemp - var.lowTemp) + 0.5) + var.lowBrightness ; set var.lowValue = min(var.midRed,var.lowRed) set var.highValue = max(var.midRed,var.lowRed) set var.redScale = (var.highValue - var.lowValue) / (var.medTemp - var.lowTemp) set var.lowValue = min(var.midGreen,var.lowGreen) set var.highValue = max(var.midGreen,var.lowGreen) set var.greenScale = (var.highValue - var.lowValue) / (var.medTemp - var.lowTemp) set var.lowValue = min(var.midBlue,var.lowBlue) set var.highValue = max(var.midBlue,var.lowBlue) set var.blueScale = (var.highValue - var.lowValue) / (var.medTemp - var.lowTemp) set var.lowValue = min(var.midWhite,var.lowWhite) set var.highValue = max(var.midWhite,var.lowWhite) set var.whiteScale = (var.highValue - var.lowValue) / (var.medTemp - var.lowTemp) if var.lowRed < var.midRed set var.redValue = floor((var.redScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) + var.lowRed else set var.redValue = var.lowRed - floor((var.redScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) if var.lowGreen < var.midGreen set var.greenValue = floor((var.greenScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) + var.lowGreen else set var.greenValue = var.lowGreen - floor((var.greenScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) if var.lowBlue < var.midBlue set var.blueValue = floor((var.blueScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) + var.lowBlue else set var.blueValue = var.lowBlue - floor((var.blueScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) if var.lowWhite < var.midWhite set var.whiteValue = floor((var.whiteScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) + var.lowWhite else set var.whiteValue = var.lowWhite - floor((var.whiteScale * (var.thisHeaterTemp - var.lowTemp)) + 0.5) if var.logging = true echo "Temp is > ", var.lowTemp, "but < ", var.medTemp echo "RGB(W) values set to -" , var.redValue, var.greenValue, var.blueValue, var.whiteValue echo "Brightness set to", var.setBrightness ; cold temp range, so just set colour to cold value but scale brightness between zero and low temp value else set var.brightScale = (var.highBrightness - var.lowBrightness) /(var.lowTemp - 0) set var.setBrightness = floor(var.brightScale * (var.thisHeaterTemp - 0) + 0.5) + var.lowBrightness ; set var.redValue = var.coldRed set var.greenValue = var.coldGreen set var.blueValue = var.coldBlue set var.whiteValue = var.coldWhite if var.logging = true echo "Temp is < ", var.lowTemp echo "RGB(W) values set to -" , var.redValue, var.greenValue, var.blueValue, var.whiteValue echo "Brightness set to", var.setBrightness ; finally, set the LED strip to the desired colour and brightness if var.RGBW = true M150 R{var.redValue} U{var.greenValue} B{var.blueValue} W{var.whiteValue} P{var.setBrightness} S{var.pixelsPerTool} F{var.F} ; set pixels else M150 R{var.redValue} U{var.greenValue} B{var.blueValue} P{var.setBrightness} S{var.pixelsPerTool} F{var.F} ; set pixels
-
@owend That's awesome, I've not had a chance to try the new code yet because 1) it's still quite hot in my small workshop and 2) I don't currently use PrusaSlicer for my toolchanger so haven't changed the code for S3D yet.
But I will give it a go.
Thanks.
-
Hey, had a go at using this today and It's not quite working. Below in my start gcode for single T3 printing, bare in mind on the toolchanger homing and ABL need to be done before a tool is picked up. What's happening is it basically get's to the point where the temp has been set and heating begins but even once at temp it just sits and does nothing but cycle through checking the tools/heaters.
I have both macros in the macro folder for ref.
M104 T-1 M140 S[first_layer_bed_temperature] ;M568 P0 A2 R[standby_temperature_delta] S[first_layer_temperature] ; set active and standby temps ;M568 P1 A2 R[standby_temperature_delta] S[first_layer_temperature] ; set active and standby temps ;M568 P2 A2 R[standby_temperature_delta] S[first_layer_temperature] ; set active and standby temps M568 P3 A2 R[standby_temperature_delta] S[first_layer_temperature] ; set active and standby temps M98 P"/macros/set_led_while_heating.g" S[first_layer_temperature] T[current_extruder] D3 G28 ; G29 ; enable mesh M116
-
@rushmere3d
I'll have a look, but probably not before the weekend -
@owend No problem, no rush.
Shall I try the set_led_by_temp as a daemon.g? rather than being called from a macro.
Thanks for your help.
-
@rushmere3d
You could call it in daemon.g
Perhaps set up a global variable so that you can only call it when you've set that variable to true.
So in your slicer haveset global.WarmUp = true
// set all temps etc
// do homing
Set global.WarmUp = falseThen in daemon.g
If global.Warmup= true
M98 P"path-to-macro.g" -
@rushmere3d
The problem was that you did not have any tools selected and I was using the selected tool to determine which heater to monitor in the while loop.This revised file will work with no tool selected.
; set_LED_while_heating.g ; Parameters can be passed for Tool number and target temp ; S = target temperature ; T = Tool number ; D = delay between checks ; example in Prusa slicer start code ; #### ; M568 P[current_extruder] R{"{heat.coldExtrudeTemperature+5}"} S[first_layer_temperature_0] A2 ; M98 P"set_LED_while_heating.gcode" S[first_layer_temperature_0] T[current_extruder] D3 ; M116 ; ### var toolNumber = 0 var thisTool = 0 if exists(param.T) set var.toolNumber = param.T var targetTemp = 120 if exists(param.S) set var.targetTemp = param.S var delay = 3 if exists(param.D) set var.delay = param.D ;echo "Tool number is ", var.toolNumber if var.toolNumber != -1 var heaterNumber = tools[var.toolNumber].heaters[0] while heat.heaters[var.heaterNumber].current < var.targetTemp M98 P"0:/macros/conditional_g_code_macros/set_led_by_temp.gcode" G4 S{var.delay} else while iterations < #tools set var.thisTool = iterations ;echo "Testing heat.heaters[tools[" , var.thisTool, "].heaters[0]]" if (heat.heaters[{tools[var.thisTool].heaters[0]}].state="standby") while (heat.heaters[{tools[var.thisTool].heaters[0]}].current) < (heat.heaters[{tools[var.thisTool].heaters[0]}].standby) M98 P"0:/macros/conditional_g_code_macros/set_led_by_temp.gcode" G4 S{var.delay} if (heat.heaters[tools[var.thisTool].heaters[0]].state="active") ;echo "active" while (heat.heaters[tools[var.thisTool].heaters[0]].current) < (heat.heaters[tools[var.thisTool].heaters[0]].active) M98 P"0:/macros/conditional_g_code_macros/set_led_by_temp.gcode" G4 S{var.delay} ; done heating, so set to white M150 R255 U255 B255 W255 P255 F0 ; set pixels
-
-
-
@nightowl said in Temperature controlled LED display:
I'm going to learn from this to control a series of neopixel LEDs to change colour depending on the spindle speed for my CNC machine, and also have 3-colour LEDs to show my machine in Safe (Green: switched on but not in use/file not loaded), Pause (Orange) and Red (Running a project).
Any thoughts on this, please?
I was thinking of buying this 1m length (of 144LEDs/m) and cutting it to length, but isn't the current rating (20A) a bit high?
Thanks
-
-
@nightowl the current consumption is up to 60mA per LED, times 144 for a 1m length is 8.64A maximum. So you will need a separate 5V PSU for them, but a 10A one will do.
-
-
I strongly advise to not put any M98 inside daemon.g as it can disrupt the main DDARRing and cause stutter in the movement. What I usually do is copy the macro inside the daemon.g and even then some commands might disrupt the movement, at least not the whole macro will cause problems. Maybe we can queue the commands in a different G-Code queue with RRF3.5 to avoid all of this.
-
@Hugsy said in Temperature controlled LED display:
I strongly advise to not put any M98 inside daemon.g as it can disrupt the main DDARRing and cause stutter in the movement. What I usually do is copy the macro inside the daemon.g and even then some commands might disrupt the movement, at least not the whole macro will cause problems. Maybe we can queue the commands in a different G-Code queue with RRF3.5 to avoid all of this.
The main issue with doing too much in daemon.g is contention for the SD card. Using M98 causes it to open the macro file, which involve several SD card accesses.
Also there should be a delay command inside the while loop in daemon.g so that there are periods of time when daemon.g id not competing for resources. This delay should normally be at least 1 second, but more is better if you don't need daemon.g to react faster to changes.