Welcome! Log In Create A New Profile

Advanced

Print Case Temperature - any benefits ?

Posted by DaveOB 
Print Case Temperature - any benefits ?
August 07, 2015 04:24PM
Hi all

New to 3D print about a month ago, and soon decided that the bed would heat better, and less print problems, if I enclosed the printer in a case / cube.

So out with some 20mm square pine, made a cube with fold-up front & top, and removable sides for working on the printer if ever needed. I think the total cost was around $20.

I moved all the electronics to outside the cube, so the air flow from the fans on the ramps board, and the power supply unit, would not affect the bed heating or print quality.
The electronics are covered with a clear acrylic cover.

So with some past experience with Arduino, I set about to modify the Marlin code to show me the Layer number ( + total layer count ) and estimated time remaining.

Latest additions are 3 cheap digital temperature sensors ( DS18B20s on a OneWire single input pin ) which update every 3 seconds and display on the graphical LCD ( in place of the 2nd and 3rd extruders as my printer only has 1 ).

Positions are :
inside cube at top
inside cube at bottom
inside electronics case

My initial reason for these was that I could monitor temperatures, and if there was a sudden temperature rise, or the temp got to above a specified level, there was a serious problem in the cube and time to shut down the heaters, sound the alarm, etc.

Could the temperature data be useful on a print settings level ? Would knowing the cube air temperature have any benefit to deciding the best settings for a print ?
Re: Print Case Temperature - any benefits ?
August 07, 2015 09:40PM
Sounds like a great addition! I'm not sure how much you can learn from monitoring the enclosure temperature that results from the hotend and bed heaters, but I'd be tempted to add another source of heat and try and get independent control of the enclosure temperature. That sounds like an ideal way to get control of ABS cooling rate for example.
Re: Print Case Temperature - any benefits ?
August 07, 2015 10:05PM
Dave,
It does sound very good.
I'd be interested in how your top/bottom temperatures compare.

I don't think these readings would modify the print settings, but they could inform you about what temps you need when printing certain sized prints that could lift at the corners etc.
Perhaps it could modify the speed of your extruder cooling fan, but you'd want that hard wired on probably.

I find that by the time my printer has heated the bed to 110c, the chamber is around 45C, which is plenty enough to start with, since by the time the print gets tall enough to matter the chamber temp has maxed out at around 64C and nothing warps.

I really like the idea of having a watcher like that, that could shut down the printer for safety. I've started something like that also, with a second display next to the main display, and will put a mini Arduino in there as the watcher. It would use a transistor to trip a relay that would shut off power to the main controller. I've not programmed it yet.

I'm sure others would be interested in the temp monitoring code as well. Please post it here if you want!


My printer: Raptosaur - Large Format Delta - [www.paulwanamaker.wordpress.com]
Can you answer questions about Calibration, Printing issues, Mechanics? Write it up and improve the Wiki!
Re: Print Case Temperature - any benefits ?
August 08, 2015 09:11AM
Quote
Paul Wanamaker
I'm sure others would be interested in the temp monitoring code as well. Please post it here if you want!

Hi Paul.

I have just solved the last hurdle. I was finding that using the DallasTemperature library, the method that it returns the temp value is ' request, wait, read ' and this can take up to 750ms that the rest of the main loop stops responding.

I have since found that removing DallasTemperature library, and using only the OneWire library, it is possible to 'request' the value, then continue in the main loop until the value is available, and then read the value. The value read takes around 3ms.

I will be documenting the code changes this evening, and here is a pic of my LCD screen showing the temp in the top of the case at 31.2 degrees Celcius ( actually it's 31.25 as I am using a 0.25 resolution, but only displaying 1 decimal place ).

Sorry the pic is a bit fuzzy - limitations of my phone camera.

I currently only have the 1 sensor installed, but the code is in and working for all 3.

The outside temp is about 22C today, and the case temp rose to 30+ within 5 minutes of starting printing.

The pic is ( as you can see ) on layer 115 or a total 254 layers, with an estimated time remaining of 47 minutes.
Attachments:
open | download - 20150808_143537.jpg (146.5 KB)
Re: Print Case Temperature - any benefits ?
August 08, 2015 12:53PM
OK. Solved, tested and working as far as I can tell.

Temperature Sensor Modifications

This is the detail of the mods I made to my Marlin firmware to add temperature sensors to my printers case, and show the temperature readings on my Graphical LCD screen.

There is a photo of the LCD screen in the post above this.

Disclaimer : as with everything I post, this was done entirely for my own use, and I take no responsibility if it does not work for you. Please ensure that you have a backup of your working firmware code before attempting this. This should only be attemped by a qualified and responsible person smiling smiley

I am using the Dallas OneWire sensors ( DS18B20 ) so that I can connect multiple sensors to the same single pin on my Ramps1.4 board.

Temperature sensors are DS18B20 sensors.

Ramps Pins diagram : [reprap.org]

Sensors :
Pin 1 ( Gnd ) - pin 1 from all sensors connected to Ground pin on Ramps1.4 Aux1 Gnd
Pin 2 ( DQ ) - pin 2 from all sensors connected to D57 pin on Ramps1.4 Aux1 D57
Pin 3 ( Vcc ) - pin 3 from all sensors connected to 5V pin on Ramps1.4 Aux1 5V

Resistor ( 4K7 ) connected between the DQ line and Vcc line ( 1 single resistor for the complete 'bus' - NOT 1 resistor for each sensor )


Code Changes :


File : Marlin.ino

at the very top of the file, add :
#include

You need to add the OneWire library to your Arduino IDE library folder if it is not already there.

File : Marlin_main.cpp

around line 60, after the code :
#if NUM_SERVOS > 0
#include "Servo.h"
#endif

add this code :
// OneWire code
// added for the case temp sensors
#include 
OneWire myds(57);   // Temperature Data wire is plugged into pin D57 ( A3 ) on the Arduino
byte DSreadstage;
byte DSresolution = 10;
unsigned long DSstarttime;
byte LocalTemp1[8] = { 0x28, 0xCC, 0xD1, 0xE1, 0x02, 0x00, 0x00, 0xE6 }; // temp sensor 1 at TOP of case - unique address
byte LocalTemp2[8] = { 0x28, 0xE5, 0x18, 0xF0, 0x01, 0x00, 0x00, 0x45 }; // temp sensor 2 at BOTTOM of case - unique address
byte LocalTemp3[8] = { 0x28, 0xE5, 0x18, 0xF0, 0x01, 0x00, 0x00, 0x46 }; // temp sensor 3 outside the case - unique address

// NOTE : the 3 Device Address values are specific to MY sensors. You will need to get the correct addresses for each of your sensors.
// See this page for instructions : 
// [www.hacktronics.com]


around line 250, after this code :
float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
bool axis_known_position[3] = {false, false, false};
float zprobe_zoffset;

add this code :
// OneWire code
float DStemp1;
float DStemp2;
float DStemp3;

and then after the code :
  #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
  delay(PROBE_SERVO_DEACTIVATION_DELAY);
  servos[servo_endstops[Z_AXIS]].detach();
  #endif
}

add this code :
// OneWire code
int resolution = 10;

// OneWire code
void dssetresolution(OneWire myds, byte addr[8], byte resolution) {

	byte resbyte = 0x1F;	// Get byte for desired resolution
	if (resolution == 12){
		resbyte = 0x7F;
	} else if (resolution == 11) {
		resbyte = 0x5F;
	} else if (resolution == 10) {
		resbyte = 0x3F;
	}
	myds.reset();	// Set configuration
	myds.select(addr);
	myds.write(0x4E);         // Write scratchpad
	myds.write(0);            // TL
	myds.write(0);            // TH
	myds.write(resbyte);         // Configuration Register
	myds.write(0x48);         // Copy Scratchpad

}


// OneWire code
void dsconvertcommand(OneWire myds, byte addr[8]){
  	myds.reset();
	myds.select(addr);
	myds.write(0x44);         // start conversion
}


// OneWire code
float dsreadtemp(OneWire myds, byte addr[8], byte resolution) {
  	byte present = 0;
	int i;
	byte data[12];
	byte type_s;
	float celsius;
	float fahrenheit;
	switch (addr[0]) {
		case 0x10:
		type_s = 1;		//Serial.println(F("  Chip = DS18S20"));  // or old DS1820
		break;
	case 0x28:
		type_s = 0;		//Serial.println(F("  Chip = DS18B20"));
		break;
	case 0x22:
		type_s = 0;		//Serial.println(F("  Chip = DS1822"));
		break;
	}
	present = myds.reset();
	myds.select(addr);
	myds.write(0xBE);         // Read Scratchpad
	for ( i = 0; i < 9; i++) {           // we need 9 bytes
		data = myds.read();
	}
	// convert the data to actual temperature
	unsigned int raw = (data[1] << 8) | data[0];
	if (type_s) {
		raw = raw << 3; // 9 bit resolution default
		if (data[7] == 0x10) {
			// count remain gives full 12 bit resolution
			raw = (raw & 0xFFF0) + 12 - data[6];
		} else {
			byte cfg = (data[4] & 0x60);
			if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
			else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
			else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
			// default is 12 bit resolution, 750 ms conversion time
		}
	}
	celsius = (float)raw / 16.0;
	fahrenheit = celsius * 1.8 + 32.0;
	return celsius;
}


In the function for :
void setup()
{


add this code :
// OneWire code
dssetresolution(myds,LocalTemp1,DSresolution); 	// added for the case temperature sensors
dssetresolution(myds,LocalTemp2,DSresolution); 	// added for the case temperature sensors
dssetresolution(myds,LocalTemp3,DSresolution); 	// added for the case temperature sensors


and after code :
void manage_inactivity()
{
  if(buflen < (BUFSIZE-1))
    get_command();

add this code :
// OneWire code
	if (DSreadstage == 0){
		if(millis() > DSstarttime + 3000){
			DSstarttime = millis();
			dsconvertcommand(myds,LocalTemp1);
			dsconvertcommand(myds,LocalTemp2);
			dsconvertcommand(myds,LocalTemp3);
			DSreadstage = 1;
		}
	} else {
		if (myds.read()) {
			DStemp1 = dsreadtemp(myds,LocalTemp1, DSresolution);
			DStemp2 = dsreadtemp(myds,LocalTemp2, DSresolution);
			DStemp3 = dsreadtemp(myds,LocalTemp3, DSresolution);
			if (DStemp1 == -127.00 || DStemp1 >= 400) DStemp1 = 0;  // very high value means no sensor detected
			if (DStemp2 == -127.00 || DStemp2 >= 400) DStemp2 = 0;
			if (DStemp3 == -127.00 || DStemp3 >= 400) DStemp3 = 0;
			DSreadstage = 0;
		}
	}



File : Marlin.h

before the code :
#ifdef DELTA
extern float endstop_adj[3];
extern float delta_radius;

add this code :
// OneWire code
extern float DStemp1;
extern float DStemp2;
extern float DStemp3;


File : dogm_lcd_implementation.h

before the line :
static void lcd_implementation_status_screen()

add this code :
// OneWire code
static void _draw_case_temp(int x, int DSsensor) {
	int y = 6;
	u8g.setFont(FONT_STATUSMENU);
	if(DSsensor == 1){
		y = 6;
		u8g.setPrintPos(x,6);
		u8g.print(ftostr21ns(DStemp1));
		lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
	}
	if(DSsensor == 2){
		y = 16;
		u8g.setPrintPos(x,16);
		u8g.print(ftostr21ns(DStemp2));
		lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
	}
	if(DSsensor == 3){
		y = 26;
		u8g.setPrintPos(x,26);
		u8g.print(ftostr21ns(DStemp3));
		lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
	}
	u8g.setColorIndex(0); // white on black
	u8g.drawBox(x+7,y,2,2);
	u8g.setColorIndex(1); // black on white
}


replace this code :
	// Extruders
	_draw_heater_status(6, 0);
	#if EXTRUDERS > 1
		_draw_heater_status(31, 1);
		#if EXTRUDERS > 2
			_draw_heater_status(55, 2);
		#endif
	#endif


with this code :
	// Extruders
	_draw_heater_status(6, 0);
	#if EXTRUDERS > 1
		_draw_heater_status(31, 1);

// my setup only has 1 extruder so removed the option for the 3rd extruder to make space for the temperatures		
//		#if EXTRUDERS > 2
//			_draw_heater_status(55, 2);
//		#endif
	#endif

	// OneWire code
	// read, calc and print the case temperature/s
	_draw_case_temp(42,1); // display the temp of the top temperature sensor
	_draw_case_temp(42,2); // display the temp of the bottom temperature sensor
	_draw_case_temp(42,3); // display the temp of the outside temperature sensor



File : ultralcd.h

after :
char *ftostr52(const float &x);

add :
char *ftostr21ns(const float &x);


File : ultralcd.cpp

before :
// Convert int to lj string with +123.0 format
char *itostr31(const int &xx)

add :
// OneWire code
// Convert float to string with 2.1 format
char *ftostr21ns(const float &x)
{
  long xx=x*10;
  xx=abs(xx);
  conv[0]=(xx/1000)%10+'0';
  if(conv[0] == '0') conv[0] = ' ';
  conv[1]=(xx/100)%10+'0';
  if(conv[0] == ' ' && conv[1] == '0') conv[1] = ' ';
  conv[2]=(xx/10)%10+'0';
  conv[3]='.';
  conv[4]=(xx)%10+'0';
  conv[5]=0;
  return conv;
}	
Re: Print Case Temperature - any benefits ?
August 09, 2015 12:02PM
Quote
DaveOB
byte LocalTemp1[8] = { 0x28, 0xCC, 0xD1, 0xE1, 0x02, 0x00, 0x00, 0xE6 }; // temp sensor 1 at TOP of case - unique address
byte LocalTemp2[8] = { 0x28, 0xE5, 0x18, 0xF0, 0x01, 0x00, 0x00, 0x45 }; // temp sensor 2 at BOTTOM of case - unique address
byte LocalTemp3[8] = { 0x28, 0xE5, 0x18, 0xF0, 0x01, 0x00, 0x00, 0x46 }; // temp sensor 3 outside the case - unique address

Just to be sure, these are the values encoded in the device's ROM? So anyone wanting to add this feature in will have to determine the code and replace these values.
Re: Print Case Temperature - any benefits ?
August 09, 2015 12:19PM
Quote
ElmoC
Just to be sure, these are the values encoded in the device's ROM? So anyone wanting to add this feature in will have to determine the code and replace these values.

Hi ElmoC

That is correct as stated in the comments in the code :
// NOTE : the 3 Device Address values are specific to MY sensors. You will need to get the correct addresses for each of your sensors.
// See this page for instructions : 
// [www.hacktronics.com]

Personally, I use the 'address finding code' to get the address of each sensor in the Serial Monitor of the Arduino IDE. Then I copy / paste that address in to the code above.

It is a reasonably quick process and the arduino sketch is quite small and quick to upload.
Sorry, only registered users may post in this forum.

Click here to login