Arcol blog Just another RepRap weblog


Heated bed controller

As almost all my previous buyer built a heated bed controller, and at least Bogdan have built one, nophead is using his brain controller to handle the heated bed temperature. So there left no choice, but build my own;-)

Everybody who is using a heated bed ended to build a controller for it. Why is that?
Because the bed without a controller can only have one temperature,
which depends on the ambient temperature, also
has a very slow warming up time (the final temperature is reached after 20-30 minutes), and
really pain in the ass to build one to the exact right temperature.

So I ended up building my own version. The heated bed kit already
comes with a 200K value thermistor. It is the same, what Rapman is using for his hot-ends.
The specification of the thermistor:

      R_{T0} = 200kOhm at 25C
      beta = 4338K

Also special thanks goes to Francois, because my controller is based on his solution.

So I used an SSR relay, to switch the heating on and off. Chris suggested in one of his articles to use a varistor between the SSR relay legs, which may (or not) prevent accidental overvoltage.
I keep that in mind, and maybe I'll add it later.
An another nice idea to have a "thermal cut-out", or even better a "thermal fuse" on the heated bed. Also a simple fuse wont hurt either. I'll keep adding them to my safety list;-)

Adjusting the circuit to the 200K thermistor

Chris' articles comes to rescue again.

He mentioned in his article, choosing the right Rs value improves the linearity.
Also he mentioned in his article, that Rs should be the resistance of the thermistor at the middle of the
temperature range, he choosed 470Ohm, which is the right value at 130C for his 10K thermistor.

So I choosed mine to be 4.7KOhm:
R_th = R0*exp(beta*(1/T-1/T0))
R_th = 200*1000*exp(4338*(1/(130+273.15)-1/(25+273.15)))
R_th = 4521.5597074176958

When I was tinkering with the bed, figured out, that
the AD readings change a little when warming.
So I double-checked his article, and also figured out, that my middle temperature should be around 50C.
I could simply calculate the temperature putting different Rs value to this formula:
T = 1 / ( ln(Rs/R0) / beta + 1/T0 )

But this time I have not stopped there. I wanted to see how it improves the AD reading.
So I dusted off my limited drawing skills, and installed jsxgraph extension on this blog.

And here is a graph displaying Rs connected parallel to R_{th}:
f(t): Rs*R_{th}/(Rs+R_{th}), where
R_th = R0*exp(beta*(1/t-1/T0))

As you can see, the overall resistance is a lot more linear:

(Vertical axis: equivalent resistance in kOhm,
horizontal axis: Temperature in Celsius)

The real circuit is like this:

(picture is stolen shamelessly from Chris' article.)

So I "quickly" draw an another graph, where the x axis is temperature, and the y axis is the AD reading (how the uC will read the circuit). So it is between 0-1023.
Here is the math:
f(t): {1023/Vfsd}*{Vref}*{R1xRth/(R1xRth+R2)}, where
R1xRth = R1*Rth/(R1+Rth),
R1 = R2*Rs/(R2-Rs),
R2 = Vref*Rs/Vfsd,
R_th = R0*exp(beta*(1/t-1/T0)),
Vref = 5.0V, Vfsd=1.1V
R0=200 [KOhm], T0=25+273.15 [K], beta = 4338[K], t is the variable
f(x) in bbZ
The Internal reference voltage(Vfsd) is 1.1V (page 251 in atmega manual).

Here is the graph:

(Vertical: temperature reading by ADC [0-1023],
horizontal: temperature in Celsius)

Adjusting the temperature table
When we display the temperature on the LCD we need to convert back the A/D reading (0-1023) into Celsius degrees.
For this we build a lookup table. There is a script for it in the reprap svn.
It has a small bug, vadc is 5.0V, while in our case it is 1.1V.
So I modified the line 92, and corrected it (notice the t.vcc/t.vadc). Here is the modified sourcecode.
max_adc = int(1023 * t.vcc / t.vadc *r1 / (r1 + r2));

Also here is the generated table:

// --r0=200000 --t0=25 --beta=4338 --r1=26700 --r2=100000
// r0: 200000
// t0: 25
// r1: 26700
// r2: 100000
// beta: 4338
// max adc: 979
#define NUMTEMPS 20
short temptable[NUMTEMPS][2] = {
{1, 528},
{52, 187},
{103, 153},
{154, 135},
{205, 122},
{256, 112},
{307, 103},
{358, 96},
{409, 89},
{460, 83},
{511, 77},
{562, 71},
{613, 65},
{664, 59},
{715, 53},
{766, 46},
{817, 38},
{868, 29},
{919, 16},
{970, -14}

So I'm going to use 100kOhm resistor, and 26.7kOhm resistance built from two resistors (22+4.7), and one 10uF tantalum capacitor for noise filtering:

Also I switch on and off the transformator using an SSR relay:

The SSR relay can be directly driven from an uC output pin (arduino in our case).

Then I display the temperature, and other useful informations (like button pressed or not) using a 2x16 chars LCD display:

This LCDs has a common interface, so they driving them from arduino is a child play. There is a premade library called LiquidCrystal for it.

Although the pinout can be different. The datasheet of what Im using can be found here.
Here is the bottom side of the LCD:

Building the thermistor circuit (voltage divider)

Warning: the tantalum capacitors has polarity, and its marked on it. Here is a closeup picture:

So here is how I put it together.
First I soldered the tantalum capacitor's '-' leg, two wires and the 22kOhm resistor together:

Then I soldered the 22kOhm to the 4.7kOhm one, also I soldered the tantalum capacitor positive leg to the 100kOhm resistor:

Finally I also soldered two wires and the 4.7kOhm resistor to the 100kOhm resistor leg. Also one single wire to the other leg of the 100kOhm resistor:

Here is built in all his glory:

SSR relay

I wanted some kind of universal solution, so instead of destroying the toroid transformator's plug, I modified an extension cord:

So instead I sacrified an extension cord;-) Also it has a lamp builtin, which is extremely useful.
Also when the SSR realy is switched on, they still conduit some uA current, enough to turn this
light on. (also the 230V still can bite you).

Here is a closeup picture:

Run the controller autonomously

All I needed a plug for the arduino:

I connected the arduino (using this plug) to Rapmans controller pcb fan output. (watch out the polarity!)
Viewing from the top, the left is the + and the right is the - (GND).

How is it working

When you turn it on, it displays the Bed temperature, the target temperature (105C by default), and the A/D reading and also the button states. (for buttons I use simply a 10kOhm resistors connected to 5V and one of the inputs, when I push the button it connects to the ground. So it is inverted, when I push the button, the reading is LOW).

When heating the bed, in total of 4 light source indicating when the bed is heating:

The led13 of the arduino itself, the SSR relay, the extension board and also on the LCD there is a small star when heating.

Also here is the modified sketch file for arduino.

I also will upload the schematic, it is almost the same what Francois draw.

Hope you liked the article. I also may will improve a little in the future.

Comments (4) Trackbacks (2)
  1. Fantastic work! You guys are really making great progress, can’t wait to try myself.

    PS could you add my blog to the planet list?



  2. Where did you get the solid state relay from that handles decent current AC? I can only find 100V DC max units. :-(

  3. wow…

  4. few days ago a \varistor that control FAN speed\ on my car died. I was confused how the darn thing can \die\ as it is just a piece of PCB with few contacts to get different resistance values so I took the \old broken one\ to check it out. What happened is that my FAN was \dying\ (had to remove all coils and rewind them from scratch) and it was pushing too much current, the \varistor\ had \protection\ from over heating that might be used for heated bed too. The piece of springy wire was soldered to the PCB, when heat reached melting temp of the solder (this is some weird solder btw, melts below 220C) the wire springed from the connection and FAN was without power. We might do something similar :)