Well, no 3D printer is complete without the ability to measure the temperature, and the preferred way of determining temperatures around 220 deg is by using a thermistor. I’m using Python and I am also making use of this great python library called PyBBIO for doing it:
Update: Alex has now fixed this, so hopefully you will no longer get an error.
To install PyBBIO, just follow the instructions on GitHub. When you get the following error:
py_compile module missing; installing to /usr/lib/python2.7/py_compile.py
read this post: Post about how to fix the py_compile module.
Ok, spoiler alert! it’s:
cd /usr/lib/python2.7 wget http://hg.python.org/cpython/raw-file/4ebe1ede981e/Lib/py_compile.py
Ok, assuming you have the PyBBIO library installed, the reading of the thermistor is straight forward:
Alex has made a nice chart to help determine the pin-out.
On the Replicape, the thermistor for the Heated Build Platform (HBP) is connected to BeagleBone pin P9_35 which is AIN6 (THERM_HBP) in the schematic above, thus the test script becomes:
# Import PyBBIO library: from bbio import * therm1 = AIN6 # pin 37 on header P9 def readThermistor(): # Get the ADC values: adc_val = analogRead(therm1) # And convert to voltages: voltage1 = inVolts(adc_val) print "AIN6 ADC value: %i, voltage: %fv" % (adc_val, voltage1) delay(500) # Start the loop: while 1: readThermistor()
Update: The above script works fine on my platform, but as I was cleaning up some code it started to NOT work and I could not figure out why. I’m used to be able to switch between “from bbio import *” and “import bbio as io”, but in the case of the latter form, be sure to call the function io.bbio_init() explicitly.
Voltage to resistance
A thermistor changes resistance value with temperature, so in order to get the temperature, we must know the resistance of the thermistor. The value read on the analog input is easily converted to volts by the formula:
where adc_val is the value read on the AIN6 pin, 1.8 is the reference voltage and 2^12 is the maximum value for the ADC (12 bits). The inVolts function used in the script above is from the PyBBIO library.
Now, according to the schematic above, the thermistor, together with a 4.7K resistor forms a voltage divider:
So R2 is the thermistor, R1 = 4.7K, Vin is the reference voltage (1.8V) and Vsense is the voltage read on the analog input (AIN6). Now rearranging to solve for R2 we get:
Converting to degrees
The thermistor in question here is from an old Cup Cake HBP. It seems Makerbot have removed all build instructions from their wiki so it’s impossible to find out which thermistor is used, but let’s say its the same one used on the MK4 plastruder, which is still in stock. It’s called B57560G104F and here is the datasheet for the thermistor. In the data sheet there is a list relating the resistance value of the thermistor to the temperature it then has.
A simple plot of the table reveals the highly unlinear behaviour of the thermistor.
This behaviour is somewhat linearized by the voltage diver, at least in the area of interest around 110 degrees C.
Here is a plot of the Vin vs. temperature :
Anyways, once the conversion chart is in place (just copypasted from the data sheet), converting to degrees becomes trivial, here is the python script:
#!/usr/bin/python from bbio import * import numpy as np therm1 = AIN6 # pin 37 on header P9 # This conversion table has been found in the datasheet for B57560G104F temp_chart = [ [0, 333964], [5, 258497], [10, 201659], [15, 158499], [20, 125468], [25, 100000], [30, 80223], [35, 64759], [40, 52589], [45, 42951], [50, 35272], [55, 29119], [60, 24161], [65, 20144], [70, 16874], [75, 14198], [80, 11998], [85, 10181], [90, 8674], [95, 7419], [100, 6369], [105, 5487], [110, 4744], [115, 4115], [120, 3581], [125, 3126], [130, 2737], [135, 2404], [140, 2117], [145, 1869], [150, 1655], [155, 1469], [160, 1307], [165, 1166], [170, 1043], [175, 934.5], [180, 839.3], [185, 755.4], [190, 681.3], [195, 615.8], [200, 557.6], [205, 505.9], [210, 459.9], [215, 418.8], [220, 382.0], [225, 349.1], [230, 319.5], [235, 292.9], [240, 269.0], [245, 247.3], [250, 227.8], [255, 210.1], [260, 194.1], [265, 179.5], [270, 166.3], [275, 154.2], [280, 143.2], [285, 133.2], [290, 124.0], [295, 115.5], [300, 107.8]] # Transpose the chart temp_chart = map(list, zip(*temp_chart)) # Return the temperature nearest to the resistor value def resistance_to_degrees(resistor_val): idx = (np.abs(np.array(temp_chart)-resistor_val)).argmin() return temp_chart[idx] # Convert the voltage to a resistance value def voltage_to_resistance(v_sense): return 4700.0/((1.8/v_sense)-1.0) # Read thermistor value and print the result def readThermistor(): # Get the ADC values adc_val = 0 for i in range(1000): adc_val+= analogRead(therm1) adc_val /= 1000.0 voltage = inVolts(adc_val) # Convert to voltage res_val = voltage_to_resistance(voltage) # Convert to resistance temperature = resistance_to_degrees(res_val) # Convert to degrees print " AIN6 ADC value: %i - voltage: %fv - thermistor res: %f - Temperature: %f deg." % (adc_val, voltage, res_val, temperature) # Start the loop: while 1: readThermistor()
This is still very crude way of doing it. The 5 degree intervals are very coarse, there is no calibration and there is very much noise on the ACD input. As seen in the test script above, I am doing an averaging of 1000. Without the averaging the values were varying some 25 degrees in room temperature.
Nop head has a good introduction to more elaborate schemes for increasing the precision, this was just a “make it work” thing..