The temperature sensor
The temperature sensor is a thermistor. The resistance of the thermistor is dependent on temperature, so measuring the resistance is sufficient to calculate the temperature. Measuring resistance with a microcontroller is usually accomplished with an A/D converter.
The PIC16F628 doesn't have a true A/D converter. It does have a voltage reference generator and a voltage comparator that can be used as a poor-mans A/D converter but since it only has 16 levels on the voltage generator, it isn't useful for any real degree of accuracy. A common way to implement A/D conversion on the low end PIC microcontrollers is to use a slope converter. The basic approach used in the extruder module is to charge a capacitor of known value through the unknown value resistor (the thermistor). By measuring the time it takes to charge the capacitor, the resistance can be determined and therefore also the temperature.
For calibration purposes, the implementation also includes a resistor of known value. Through software control, the capacitor can be charged through either the known resistor or through the thermistor. The known value measurement provides a calibration point that can be used to correct any errors in the measurements of the thermistor. Note: the calibration resistor is not currently used, and the temperature is calculated with a good degree of accuracy from first principles knowing the CPU clock rate etc. In future it may be useful to use the calibration resistor as a double check. Taking advantage of the calibration resistor is just a software change.
In general complexity is offloaded to the host software so that the firmware can be kept simple. The firmware does not perform any final temperature calculations, it just makes raw timing measurements and passes them to the host controller to finally determine the actual temperature.
Timing the capacitor charge involves first discharging the capacitor and then starting the capacitor charge. The number of ticks of a timer is counted until the capacitor is charged.
The complicated part of the sampling the resistance is getting the timing correct. If the capacitor charges too quickly, the number of ticks elapsed will always be very low and since it is an integer value it will have very little accuracy. To maximize accuracy, it is important that the timer counts as high as possible during the sampling period. However if it counts too high, it will overflow and the sample becomes useless.
Capacitor charging is exponential so it never quite charges fully, so rather than waiting for a 100% charge, the firmware only waits until it reaches a particular percentage of full charge. The voltage comparator is used to determine when the capacitor reaches the appropriate level. The voltage comparator threshold is the first important parameter for the timing. The PIC voltage comparator works by comparing the input voltage to the voltage reference module output. The voltage reference is set by two parameters, a 4 bit VR value and a high/low range flag. The firmware always uses the high range, so the voltage reference output is determined by the following equation:
VREF = 1.25 + 5 * VR / 32
At powerup, by default VR is 3 however this can be changed by the host at any point in time.
The time measurement is accomplished using an 8 bit timer TMR0 which counts at an adjustable rate. The rate is specified by an 8 bit prescaler. The watchdog prescaler is assigned to the timer, which is a value 1:1, 1:2, 1:4, 1:8, ..., 1:128 (ie a power of 2). This parameter (PS) can also be adjusted under control from the host software. At powerup, it is initially set to 1:128.
The two parameters VR and PS together define the timing behaviour. It is intended that the host controller software will dynamically adjust these parameters to keep the timer values as close to 255 as possible, without overflowing. If an overflow occurs the timing should be slowed down (or VR increased) so that overflow stops. If the timer values are too low, the timing should be sped up (or VR decreased) to increase the timer values. At any stage, with the knowledge of the current PS and VR values and the charge time, the host software can calculate the resistance and therefore the temperature.
This automatic ranging behaviour allows for the most accuracy possible throughout the desired temperature range. To make the most of auto-ranging capability, the capacitor value should be matched to the thermistor range. The capacitor value is currently assumed to be 10nF and is hard coded. Since ideally this depends on the thermistor used, the capacitor value should be stored in the application preferences. 10nF will not be suitable for all thermistors. The ideal capacitor value can be calculated:
Given a desired maximum temperature and level of accuracy, this calculator will determine the appropriate capacitor value to match your thermistor.
You should aim to make the resulting minimum measurable temperature less than your ambient temperature, but that isn't essential. If the minimum temperature is very low, you can afford to increase the maximum measurable temperature or the decrease error limits.
NOTE: There is a difference between R0 and Rz. The thermistor Rz is the resistance at 0°C. So it is different from R0 on the spec sheet which is sometimes at 20°C and sometimes at 25°C. This basically compresses three parameters into two. R0/t0 from specs can be converted to Rz, see Measuring Thermistor Beta.
To verify the correct and optimal operation of the temperature measurement, the poke utility can be used. Check that the returned timer values are as close as possible to 255 for low temperatures. As the temperature rises the value should drop. This naturally leads to less accurate measurements at higher temperatures. Resetting the ranging value should be tested to ensure that the timer values can be increased to useful ranges for the higher temperatures as well.
[todo] include sample steps for test
Note, an interrupt occurring during the timing routine will upset the timing. Shouldn't this disable interrupts??!
Ah, actually it shouldn't disable interrupts because the sample time is too long. However if an interrupt occurs, it should set a flag to tell it to disregard that particular sample
Host controller details
The host controller software currently does not dynamically adjust the timing parameters as intended. With appropriate capacitor selection, it still behaves adequately this way. At room temperatures precision is better than ±1°C. At high temperatures of around 180°C accuracy is approximately ±10°C. This is generally acceptable for production, but completing the dynamic timer adjustment code will improve this accuracy.
The important functions are:
- getDeviceTemperature: Internal function to request current temperature. This is periodically called from a polling routine to update the current temperature.
- calculateResistance: Calculates the resistance of the thermistor in ohms
- calculateTemperature: Calculates the temperature (celsius) given the thermistor resistance using the known thermistor parameters, β and Rz.
The heater output
The heater is fully software controllable with a variable power output. By using the temperature sensor and also adjusting the heater element power output the extruder barrel temperature can be maintained at a stable temperature.
At its most basic, there are two characteristics involved in extruder heating that oppose each other. The first is the energy being put into the heater. Barring any other effects, as energy is put into the heater it will continually become hotter and hotter. However the opposing characteristic is heat loss. While the energy input is a fairly simple and known figure, the energy losses are very complex and fundamentally unpredictable. The losses depend on the size and materials the extruder is made from, the shape and even subtle effects from the colour, humidity, altitude etc. Importantly it also depends on ambient temperature.
While not completely predictable there are some basic trends. The further away the extruder temperature is from ambient temperature, the greater the losses will be. Knowing this and measuring the heat loss characteristics of the extruder allows the software to predict what the extruder temperature will be. For any given amount of input energy, an equilibrium state will eventually be reached where the two opposing characteristics are in balance. It turns out that the relationship between the input energy and equilibrium temperature is fairly linear. The most important factor is the physical design of the extruder. The other variables like humidity have a relatively small impact, so a linear equation (ie an equation of the form y = mx + b) gives a pretty good approximation to the overall behaviour even over time.
In order to determine what the parameters of the linear heating equation are, there is a diagnostic tool within the host software that runs the heater at a range of different energy input levels. It is called the Heater Profiler and is accessible from the Diagnostics menu. At each level it waits to see what temperature the extruder stabilises at and records it as a data point. Once data points have been collected across the entire power range, linear regression can be used to determine the heating gradient (hm) and heating intercept (hb) point. These parameters are entered into the host software preferences so the it can accurately control the output.
Note: currently the heater profiler only collects the data points and prints them to the console. The regression step is not currently automatically performed and must be done in some other package in order to obtain hm and hb. It should really be implemented directly in the profiler.
There is a very simple method of controlling a heater temperature sometimes referred to as "chop-chop" control or "bang-bang control". The heater element is turned on at full power until the desired temperature is reached and then turned off. Once the temperature drops the heater will turn on again, repeating the cycle. This is the method you frequently see in a lot of electrical heaters. It is very simple because it doesn't require control of the heater output power, it is just full on or full off. The problem with chop-chop control is that the heating has a sort of momentum effect. When you turn off the power, the heat will continue to increase for some time. Once the temperature drops and you turn on the power again, it will continue to drop for some time before the heat starts to come up again. The extent of the effect depends on the specific heat capacity of the extruder and its thermal conductivity. Generally it results in a temperature that swings pretty wildly around the goal temperature which is less than ideal.
Alternatives to bang-bang control
Obviously by putting in the right amount of power to start with and maintaining it, the heater will reach a nice stable equilibrium point directly without any of the wild variations.
That's all very well, but an underlying assumption is that you're not changing the physical characteristics of the extruder as you go, and thereby upsetting all of the equation parameters you just computed. By pushing plastic into the extruder though, you are doing just that. Also as the hot plastic leaves the extruder it takes some energy with it and bringing in new cool plastic draws some energy up into the plastic. That means while you are extruding, the temperature equilibrium will be relatively low and when you stop extruding it will be relatively high.
To compensate for this energy loss, the target temperature is set higher than the melting point of the plastic.
Note: A more elaborate scheme (which was the original intention) might be to continuously monitor the temperature vs input power and dynamically adjust the power output based on a more sophisticated physics model. This may provide an even more stable temperature and avoid the need for configuring the heating parameters. This approach could also converge much more quickly to the desired temperature.
The firmware controls the heater by using pulse width modulation (PWM). The PIC16F628 only has a single PWM output, which we want to use for controlling the extruder motor speed. Instead a slow software PWM implementation is used. Although it has a relatively slow period, the effect of the pulsing will not really be seen in the final temperature because of the relatively huge specific heat capacity of the extruder thermal mass.
The firmware has four 8 bit heating parameters:
The two parameters heat0 and heat1 each specify a heater output level. The two parameters temp0 and temp1 specify temperatures. These temperatures are specified in terms of the PIC timer temperatures, the same values that are returned by the temperature sensing firmware.
The two temperatures define three temperature zones. The low zone is anything cooler than temp0. The middle zone is anything between temp0 and temp1 and the high zone is anything higher than temp1.
Timer1 is used to implement the low rate PWM. A counter heatCounter cycles up to the PWM period. The position of this counter within the period is used to control the on/off of the heater transistor to provide the appropriate duty cycle (equivalent power output).
Within the low zone, the duty cycle is set to output at heat1 (the hotter of the two power levels). Within the middle zone, the duty cycle is set to output at heat0. If the temperature reaches the high zone, it will switch the heater off completely so that it returns to one of the two normal operation zones.
This is not vastly different from a pure chop-chop controller, however because it is switching between two intermediate values rather than fully on and fully off, the temperature stays within a narrow range without large swings.
It is intended that for simple operation or where no thermal characteristics are known, the firmware can also be used in the simple chop-chop mode. In this case, set both heat0 and heat1 to maximum and temp0 and temp1 to the desired temperature.
Host controller details
The host software uses the temperature specified in the preferences to choose the temperature zones:
- temp0: 10% higher than the chosen temperature
- temp1: 20% higher than the chosen temperature
These temperatures are then used to select the two heater outputs according to the linear heating equation.
Note, the 10% and 20% values were fairly arbitrary. Some investigation should be done to determine the ideal figures, or perhaps it could be made adaptive in some clever way. Thoughts? Maybe it could be a preference setting instead.
In the end, the two heating zones should probably correspond with the power needed to keep the extruder at the right temperature while extruding, and while idle. It currently only does that by guesswork.
Testing the Extruder I/O
Testing involves using the Extruder Exerciser, which is launched from the Diagnostic menu in the main RepRap host application.
- Enable the heater by ticking the tickbox
- Type in a temperature into the temperature box (press enter after typing in the number for it to take effect). 100°C would be a good starting point.
- The temperature should reach the target and then stop pretty much dead on target and stay there. It takes a while to get there.
- It's probably a good idea to try a couple of other temperatures too.
Temperature gets too hot or swings a lot
- hb and hm are probably wrong.
- If it is going more than 20% higher than specified, then the thermistor characteristics are probably wrong too. Remeasure them.
Temperature is never reached
- hb and/or hm are wrong. To increase the temperature, try decreasing either or both. It may be worth re-running the heater profiler tool as well.
Temperature is always shown negative
- You have too many zeros in your value for the temperature system's capacitor.
The motor driver
- Extruder Controller API
- A Stripboard Extruder Controller - This includes some details on heater element sizing, etc.
- Measuring Thermistor Beta for an unknown thermistor
-- Main.SimonMcAuliffe - 24 Jan 2007