NTC-thermistor incubator with Arduino
Recently, when I stuck with limited lab equipments and decided to produce some for my agricultural post-harvest related research, my eyes fixed with Arduino! This is enough to wake up my old time hobby with electronics (what I really mean was soldering, XD). I never touch them for the past 15 years. I am a total noob in this matter. Arduino recreates a new passion, just like when I learned GNU/Linux some 10 years ago.
Last year, I purchased an Arduino UNO R3 for the purpose of learning and found this is incredibly simple to deliver solutions in my field. I do not need (and do not want too) to learn assembler or AVR languages in depth, just to produce thermocouple logger for cacao fermentation or to build a small scale DC powered incubator for example.
Arduino UNO (pic. from www.arduino.cc)
HARDWARE SETUP
Enough talking, now I proceed to the core of the article, a tutorial for NTC-thermistor incubator. In this occasion, a “brain” for incubator using negative temperature coefficient thermistor is explained, hopefully clear enough for a beginner like me. The setup is as follow:
- The MCU: ATmega328P-PU chip with Arduino UNO R3 bootloader (howto burning bootloader OR burning bootloader for ATmega328 (without P) ).
- The probe: 3x 10kΩ NTC thermistors
- The output: a led and a buzzer
- Some electronic parts: 4x 10kΩ±5% and 1x 2.2 kΩ±5% resistors, 1x 100nF and 2x 22pF capacitors, 1x opto-isolated 5v relay module, 1x 16Mhz crystal, and some jumper cables.
- The USB to serial: 1x FTDI 5v basic (that also acts as power source).
- Planned electronic parts: 1x double digits 7-segment display and 2x 74HC595 chips (will be explained later in next part)
All of these were purchased from local online shops (I live in Indonesia), i.e. SFE-electronics, iseerobot, famosastudio, geraicerdas, kedairobot, klinikrobot, and many others.
At first, I followed the Arduino standalone tutorial (or from a youtube video if you like). This is the result.
To make things a litter easier, I produced homemade breakout for my triple thermistors with this schema:
Then I slowly added one component after another.
- FTDI basic, with pinouts connected to VCC, GND, CTS (GND), TX (pin 0), RX (pin 1), and DTR + 100nF (pin 0).
- Thermistor breakout is connected to VCC, GND, pin A0, pin A1,and pin A2.
- Relay is connected to VCC, GND, and pin 3.
- Buzzer is connected to pin 4 and GND.
PROGRAMMING
Now it comes to the interesting part: programming. Thanks to Arduino developers and community around the world. Microcontroller programming could not be more fun than before (considering I do NOT have an electronics background). You may visit the official forum, instructables, adafruit, sparkfun and too much resources to read on the net.
Firstly, thermistor runs on the principle of changing resistance upon increase/decrease of environmental temperature. After some reading, I decided to use Steinhart-Hart equation (others may use lookup table), hence the codes (frankly, taken from adafruit page with some modifications) are in the two separated functions (getResistance and getTempC). Since the explanation on the Internet is quite extensive, already, I do not find any use to re-pasting them here (you may download the whole program at the end of this article).
Next step is to check whether probes are working in the
expected environment (i.e. 0-70°C). Since I have triple thermistors, I can
afford to lose two of them at maximum to get a temperature value. Hence, the
function is called checkProbe.
#define TPin1 A0 //Thermistor Analog Pin A0#define TPin2 A1 //Thermistor Analog Pin A1#define TPin3 A2 //Thermistor Analog Pin A2int termostatValDivider = 0;float termostatVal = 0.00;int messageIndex;void checkTempProbe(){//resetting values firsttermostatValDivider = 0;termostatVal = 0.00;//if measured 0 < temperature < 70, probe in good condition, otherwise malfunction
//TPin1if (getTempC(getResistance(TPin1),TPin1)>0 && getTempC(getResistance(TPin1),TPin1)<70 p=""> 70>
termostatVal += getTempC(getResistance(TPin1),TPin1);termostatValDivider +=1;} else {//message index 91messageIndex = 91;//debuggingSerial.println("Probe 1 malfunction");}//TPin2if (getTempC(getResistance(TPin2),TPin2)>0 && getTempC(getResistance(TPin2),TPin2)<70 p=""> 70>
termostatVal += getTempC(getResistance(TPin2),TPin2);termostatValDivider +=1;} else {//message index 92messageIndex = 92;//debuggingSerial.println("Probe 2 malfunction");}//TPin3if (getTempC(getResistance(TPin3),TPin3)>0 && getTempC(getResistance(TPin3),TPin3)<70 p=""> 70>
termostatVal += getTempC(getResistance(TPin3),TPin3);termostatValDivider +=1;} else {//message index 93messageIndex = 93;//debuggingSerial.println("Probe 3 malfunction");}//get temperature from available probe(s) onlyif (termostatVal!=0 || termostatValDivider!=0) {termostatVal /= termostatValDivider;} else {//message index 99messageIndex = 99;//debuggingSerial.println("All probes malfunction");}}
To call the function is pretty basic.
void loop() {//resetting message indexmessageIndex=0;//check probe, if failed, switch modecheckTempProbe();//debugging//Serial.println(termostatVal);….}
The rest is to create an action function based on temperature reading,
i.e. I wanted a range of temperature in between 27-33°C.
#define heatingTime 5000 //heatingTime to let heater warms up#define coolingTime 10000 //coolingTime to maintain temperature at range.#define upperTemp 33 //max allowed temperature#define lowerTemp 27 //min allowed temperatureint led = 13;int buzz = 4;void loop() {…//main programif (messageIndex==99) {//thermistor probes failureaction(99);} else if (termostatVal>upperTemp) {action(1);} else if (termostatVal
action(2);} else {action(0);}}//heater actionvoid action(int mode){//debuggingSerial.print("Action mode: ");Serial.println(mode);if (mode==99) {//all thermistor failures//buzingbuzzing(messageIndex);//blinkingblinking(messageIndex);} else if (mode==1) {//message 11messageIndex = 11;//debuggingSerial.print("termostat value:"); Serial.print(termostatVal); Serial.print((char)176); Serial.println("C, Heater OFF");Serial.print("ALERT: "); Serial.print(termostatVal); Serial.print((char)176); Serial.println("C: temperature too high!");//heater OFFdigitalWrite(relayPin,relay_OFF);//buzzer ONbuzzing(messageIndex);//blinking ONblinking(messageIndex);} else if (mode==2) {//message 12messageIndex = 12;//debuggingSerial.print("termostat value:"); Serial.print(termostatVal); Serial.print((char)176); Serial.println("C, Heater ON");Serial.print("ALERT: "); Serial.print(termostatVal); Serial.print((char)176); Serial.println("C: temperature drop!");//heater ONdigitalWrite(relayPin,relay_ON);//buzzer ONbuzzing(messageIndex);//blinking ONblinking(messageIndex);} else {//message 10, all goodmessageIndex = 10;//debuggingSerial.print("termostat value:"); Serial.print(termostatVal); Serial.print((char)176); Serial.println("C, Heater REGULATED");//cooling first then heatingdigitalWrite(relayPin,relay_OFF);delay(coolingTime);//heater ON for predefined timedigitalWrite(relayPin,relay_OFF);delay(heatingTime);//blinking ONblinking(messageIndex);}}//blink actionvoid blinking(int mode){if (mode==11) {//blinking, high tempfor (int i=0;i<5 i="" p=""> 5>
digitalWrite(led, HIGH);delay(200);digitalWrite(led, LOW);delay(200);}} else if (mode==12) {//blinking, low tempfor (int i=0;i<5 i="" p=""> 5>
digitalWrite(led, HIGH);delay(500);digitalWrite(led, LOW);delay(500);}} else if (mode==99) {//blinking all probes malfunctionfor (int i=0;i<10 i="" p=""> 10>
digitalWrite(led, HIGH);delay(100);digitalWrite(led, LOW);delay(50);}} else {//blinking, normaldigitalWrite(led, HIGH);delay(500);digitalWrite(led, LOW);delay(500);}}//buzzer actionvoid buzzing(int mode){if (mode==11) {//buzzing, high tempfor (int i=0;i<5 i="" p=""> 5>
digitalWrite(buzz, 100);delay(200);digitalWrite(buzz, 0);delay(200);}} else if (mode==12) {//buzzing, low tempfor (int i=0;i<5 i="" p=""> 5>
digitalWrite(buzz, 50);delay(500);digitalWrite(buzz, 0);delay(500);}} else if (mode==99) {//buzzing all probes malfunctionfor (int i=0;i<10 i="" p=""> 10>
digitalWrite(buzz, HIGH);delay(100);digitalWrite(buzz, LOW);delay(50);}} else {//no buzzing}}
All are (almost) done, except for readable message with double digits 7-segment. You may download the code from here. No github account yet :(.
TIME FOR FUN
Lets connect the FTDI to a USB port.SNEAKPEAK
Part 2: Multi buttons input for single Arduino analog pin
Part 3: Integrating double digits 7-segment (coming soon)
Enjoy!
Comments