Monday, December 14, 2015

DIY Hot End - Arduino PID control






So I really want a 3D printer.  I am creating some components to mount on my mill as a printing kit.  Possibly something usable by others?  This is how attempted to create my first hot end.

What is a hot end?

This part of a 3d printer is the melting point of the print media.  Most are a print nozzle and heater mounted in an aluminum block.  The media is feed into this block and the media in liquid form comes out the nozzle. I was shocked at the size of the nozzle.  REALLY small.  There is a tube to feed media that is cooled to ensure media melts only near the nozzle.  Fans are typical on the heat sink.


Hot End Hardware

I purchased a low cost clone hot end from amazon.  My thoughts were that I could learn something from a fairly inexpensive product.  The heater is 40 Watt and it contains a 100KOhm 3950 thermistor.


Arduino Hot Heat Control

The next step was how to control the temperature of the hot end.  I had an Arduino Yun available.

 ArduinoYun Official Site


The following is how I fulfilled my fulfill my requirements.

Temperature Measurement 

I have to know the temperature before I can control it. A thermistor (pre-installed in hot end) basically is a resistor that changes value (non-linearly) bases on the temperature.  I found a great explanation of them and how to measure with the arduino. Thanks to 'lady ada' for all the great input.  Well written article. See: How to connect and measure a thermistor with an arduino.   I used a 10K balance resistor.  I do not believe my temperatures are ready correct values yet but the values are moving as I would expect.  I will figure out the scaling and report back. If I build the next hot end it will contain a thermocouple.

<Need Photo of the thermistor here...>

Control of the heater output

The 12VDC 40W heater needs to be regulated.  The cheapest/simplest method I could find was to use a TIP120 NPN transistor.  They are really common and handle a fair amount of power.  I found a great blog/explanation here: How to switch higher current loads with a transistor and arduino.  I use the PWM output to switch the transistor using the built in Arduino PWM.  This seems to work well.  I put an LED between the Output pin and ground to give general visual indication of the output.  The load power is 12VDC.  I also paralleled a small case fan with the 40W heater.  I will most likely move this to another output and base the speed on temperature instead of heater current but I like seeing it spin up and then stop.

<Need photo of the heater here...>

As suggested in the comments, I have updated this project to use a MOSFET. I learned about using them here: High-Power Control: Arduino + N-Channel MOSFET.  I have found it allows more current flow and better heat control.  I used a BUZ91A (amazon item)

A control logarithm (Arduino PID)

The Arduino PID control library is mature and there are some great explanations/insights available.  I learned reading Improving the Beginner’s PID – Introduction.  I am still working on the tuning.  I also created a simple sketch based on the Arduino AutoTune library.  Another great post/tutorial  from the same author (much thanks Brett Beauregard) here that demonstrates his code.  I played with this for a while to get it to work.  You want to play with the step and start point so that the loop can move the output and see resultant changes.  That is how it learns (I think).  Again, I am still tuning/learning but my loop trains in on a temperature quickly enough and stabilizes very well.

Side Note:

Notice the PID goes to full scale (255 is max) in a few seconds of a change.  I think I like this response because I'm sure the plastic melting load will be significant.  I would say starting, stopping and speed changes is when the temperature will be an issue.

Communications of setpoint and status

I use the basic USB serial communications of the Arduino for the moment.  The unit constantly ouputs the current temp, current heater output level and current set point.  The arduino also listens for a single input value that it sets as the new set point when it receives. The near future plan is to add a Rasberry pi to the mill.  Hopefully it will control this set point using a Web API published through the Yun's web functionality.

Notice the PID goes to full scale (255 is max) in a few seconds.  I like this response because I'm sure the plastic melting load will be significant.  I would say starting, stopping and speed changes is when the temperature will be an issue.





Arduino Sketch

This should run on any Arduino.. Enjoy.  Let me know if does you any good and please share improvements.

#include <PID_v1.h>
// Analog output pin
#define outputPin 9
// thermistor analog pin
#define THERMISTORPIN A0
// how many samples to take and average
#define NUMSAMPLES 5
// how long between pid/sampling
#define SAMPLETIME 1000
//Define Variables we'll be connecting to
double Setpoint, currentTemp, Output;
//Specify the links and initial tuning parameters
PID myPID(&currentTemp, &Output, &Setpoint,15,.3,0, DIRECT);
void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
  pinMode(outputPin, OUTPUT);
  //initialize PID setpoint *C
  Setpoint = 110;
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(SAMPLETIME);
  //pid Autotuner
}
void loop() {
  if (Serial.available() > 0) {
    // get incoming byte:
    Setpoint = Serial.parseFloat();
  }
  uint8_t i;
  double average = 0;
  // take N samples in a row, with a slight delay
  for (i = 0; i < NUMSAMPLES; i++) {
    average += analogRead(THERMISTORPIN);
    delay(10);
  }
  average /= NUMSAMPLES;
  currentTemp=resistanceToC(inputToResistance(average));
  myPID.Compute();
  analogWrite(outputPin, Output);

  Serial.print("Set Point: ");
  Serial.print(Setpoint);
  Serial.println(" *C)");
  Serial.print("Temperature: ");
  Serial.print(currentTemp);
  Serial.println(" *C)");
  Serial.print("PID output ");
  Serial.println(Output);
  delay(SAMPLETIME);
}
double inputToResistance(double input) {
  // funtion to convert the input value to resistance
  // the value of the 'other' resistor
  double SERIESRESISTOR = 10000;
  input = 1023 / input - 1;
  return SERIESRESISTOR / input;
}
double resistanceToC(double resistance) {
  // funtion to convert resistance to c
  // temp/resistance for nominal
  double THERMISTORNOMINAL = 118000;
  double TEMPERATURENOMINAL = 25;
  // beta coefficent
  double BCOEFFICIENT = 3950;
  double steinhart;
  steinhart = resistance / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;   // convert to C
  return steinhart;
}



Basic Diagram


I love EasyEDA.  I will probably order a custom board once I add a few more options to the prototype.  See the diagram in an editable link here: Mill Hot End Control







Looks like this is going to work well.  I may update the post as progress is made.  Thanks for all the great input from those mentioned above and elsewhere.




16 comments:

  1. Why there is nothing connected to A0 ?

    ReplyDelete
    Replies
    1. I corrected the wiring diagram. Sorry about that.

      Delete
    2. Damon'S Random Ramblings: Diy Hot End - Arduino Pid Control >>>>> Download Now

      >>>>> Download Full

      Damon'S Random Ramblings: Diy Hot End - Arduino Pid Control >>>>> Download LINK

      >>>>> Download Now

      Damon'S Random Ramblings: Diy Hot End - Arduino Pid Control >>>>> Download Full

      >>>>> Download LINK SH

      Delete
  2. I put a wire between resitor and thermistor connected to A0 and it works better.

    ReplyDelete
  3. as for the sensor, connect the ntc to supply and A0 and from A0 to ground connect a 100k resistor.

    As for the heater , use a 10k resistor to the gate of the mosfet and the gate to ground use a 100k resistor. mosfets will drive the heater to its full power and consume less current..

    ReplyDelete
    Replies
    1. Thanks Jason for the input. I have actually switched this system over to use a mosfet. I will add an update to the post.

      Delete
    2. Hi

      I just finished working on a project , A PID controller .. it is available on tindie ..
      https://www.tindie.com/products/JasonKits/3d-printer-filament-joinerfuser-pid-controller-/

      Delete
  4. Hi Damon,

    Thank you! This is exactly what I have been looking for. Of a couple PID temp control systems I've found, this seems the most simple. will be very keen to implement once you update the project with details on MOFSET.

    ReplyDelete
    Replies
    1. I have a very similar off the shelf cheap hot end like yourself. I tried this out using the TIP120 NPN and set the target temp at 150, It reached this at which point the PID output lowered and carried on lowering to 0 unfortunately the actual temp kept on rising to 240 at which point the transistor started to melt the breadboard. I have triple checked my wiring and changed none of your code. any thoughts?

      Cheers

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Hello,
    I hope your project is going well and thank you for sharing it.
    I just ordered a ready to to 3D printer, but then I got an idea when I was looking at the spare parts that are available for these printers.

    My idea is that could I make an injection molding device from a 3D printer hot end. Then I found your blog. You have actually done already almost everything what I was planning.

    I was thinking that I would need a 3D printer hot end which has a stepper motor attached to it. Then I would feed pla filament through the hot end into a mold. The control would be done with arduino and some simple buttons.

    Since you have basically done all that already, could you perhaps recommend me which components I should order? I think these are what I would need:
    -3D printer hot end with stepper motor feeding (maybe this has the temperature sensor also already attached?)
    - power electronics (mosfet?) for the heating element
    - arduino UNO (this I already have)
    - driver electronics for the stepper motor, maybe some H bridge?
    -buttons to start/stop heating and controlling the stepper motor start/stop and speed

    What do you think, am I missing something obvious? I already have a CNC router which I could use for making the molds and also for making the construction for the injection molding machine.

    I hope to hear your comments.
    -Erik

    ReplyDelete
  7. after one line execute of gcode i want to check temperature but by this it can take very time for compute so after onle line execution x and y moving direction stopped for some time...please give me solution of it

    ReplyDelete
  8. useful information on topics that plenty are interested on for this wonderful post.Admiring the time and effort you put into your b!..
    3d printing

    ReplyDelete
  9. Thank you . I copied this code,completed wiring and start began work :)

    ReplyDelete
  10. I was surfing net and fortunately came across this site and found very interesting stuff here. Its really fun to read. I enjoyed a lot. Thanks for sharing this wonderful information. Arduino YUN for Beginners

    ReplyDelete
  11. years later and your project is still helping people. Im using this to create a diy pop bottle to petg filament extruder. more fun little tinkets, toys and models for my kids and I to get creative with.

    ReplyDelete