Measuring temperatures with TMP03/04 (Part 7)

Part 12345, 6, 7, 8

Here is a pretty trivial example of use of the TMP03/04 sensors. The aim of this system is to prevent a heated zone to overheat. When the temperature rises above a certain level, the fan is turned on (a 12 V model). Conversely, when the temperature resumes to normal condition, the fan is turned off. This is a plain simple closed-loop operation.

Note: The principle applies to the print area of an additive 3D printer. In case of overheating condition, the heat is transferred from the grind wheel of the filament drive to the filament itself. Consequently the filament which softens and fails to be driven resulting in print failure. Blah !  The picture below shows how I implemented the solution to a makerbot 2x printer.

fan_controller

Some refinements where added to the system such as a forced mode which allows the operator to take control over the automated process. Also an hysteresis is implemented in order to avoid heavy duty on/off cycles to occur. Here is a quick and dirty illustration of the principle of operation of the hysteresis.

hysteresis

The electronics are quite simple and is sketched below:

fan_control*

The Arduino board MUST be fed with an external 12 V DC power supply in order to comply with the fan specifications. The black wire from the fan is switched to ground by the transistor when the gate of this transistor is set to a high level through a 100 Ohm resistor. The transistor can be any from the N-Channel MOSFETs such as IRF530, IRF540, IRFZ34, IRFZ44 or their equivalents. Check the pin-out and the resistor coding in this document: Electronics pinout sheet rev4

The push button (force mode) is wired to the sensing PINB1 (aka Digital pin 8) and an appropriate biasing is done by software. The wiring of the TMP04 sensor calls no particular comment. The data pin is wired to PIND7 in order to comply with the examples which come along with the library.

Note: if your fan features additional wire (probably yellow or white), leave this wire unconnected has it is likely that this wire carries the rotational speed information.

Important: make sure that the flat side of TMP04 sensor is in close contact with the heated surface. Adding a specific thermal grease may help in the thermal bounding. Use appropriate retaining plate in order to keep the sensor in place.

Here is an example of use of the TMP04 along with its ancillary components. It is used to cool the printing chamber when the temperature exceeds a certain value in order to avoid the softening of the ABS wire while it travels through the driving mechanism (grind wheel)

Here is the related code:

/* include libraries */
#include <PlainTMP0x.h> /* TMP0x sensors library */

/* Create objects */
PlainTMP0x TMP; /* Create an instance of the TMP object */
/* Timing variables */
const uint32_t _interval = 2000;
int32_t _now, _lastTime;
/* Fan related variable */
uint8_t _fanState = 0x00;
uint8_t _force = 0x00;
/* User defined variables */
const float _tempSetPoint = 40.0;
const float _halfHysteresis = 0.05;

void setup(void) 
{
	Serial.begin(115200);
	TMP.InitializeTMP(TMP_MOD_TMP04, &PORTD, PIND7, TMP_UNI_CELSIUS, 16);
	_lastTime = millis();
	/* Set push button pin */
	DDRB &= ~(1 << PINB1);
	PORTB |= (1 << PINB1);
	/* Set fan driver pin */
	DDRB |= (1 << PINB0);
	PORTB |= (1 << PINB0);
	/* Check fan */
	delay(2000);
	PORTB &= ~(1 << PINB0);
	delay(2000);
}


void loop(void) 
{	
	/* Sense push button pin */
	if (~PINB & (1 << PINB1)) {
		_force ^=  0x01;
		Fan(_force);		
		while (~PINB & (1 << PINB1));
	}
	_now = millis();
	if ((_now - _lastTime) >= _interval) {
		/* run measurement */
		float temperature = TMP.Temperature();
		if (!_force) {
			if (temperature > (_tempSetPoint + _halfHysteresis)) {
				Fan(0x01);
			} else if (temperature < (_tempSetPoint - _halfHysteresis)) {
				Fan(0x00);
			}
		}
		_lastTime = _now;
		/* Print data */
		float time = (millis() / 1000.0);
		Serial.print(time, 1);
		Serial.print(";");
		Serial.print(_tempSetPoint + _halfHysteresis, 2);
		Serial.print(";");
		Serial.print(_tempSetPoint, 2);
		Serial.print(";");
		Serial.print(_tempSetPoint - _halfHysteresis, 2);
		Serial.print(";");
		Serial.print(temperature, 2);
		Serial.print(";");
		Serial.print(_fanState * 10);
		Serial.println();
	}
}

void Fan(uint8_t state) 
/* Set fan state  */
{
	if (state && !_fanState) {
		_fanState = 0x01;
		PORTB |= (1 << PINB0);		
	} else if (!state && _fanState) {
		PORTB &= ~(1 << PINB0);
		_fanState = 0x00;	
	}
}

Those who already use PlainTMP library may be confused with the:

TMP.InitializeTMP(TMP_MOD_TMP04, &PORTD, PIND7, TMP_UNI_CELSIUS, 16);

As I reworked many libraries, I decided to harmonize their behaviors. A description of the brand new PlainTMP will be issued and described in the next coming post

Enjoy !

Leave a Reply

You must be logged in to post a comment.