Make your own Incubator: learning by doing

This article is part of: BioLab Kitchen.

Table of content

I decided to play the game of building my own incubator. To do so, I will follow the BioHack Academy's instructions. I don't have a lot of experience with electronics but the instructions seem to be made to learn by doing. On this page you will find some useful links if you need a basic reminder.

These two links can also be useful to better understand how to build an incubator:

Let's play!

List of materials

I followed the Bill of Materials from the BHA instructions to harvest all components. Because I'm doing this project with the FabCity Hub, I have access to the Fablab Barcelona's electronic stock to grab some components.

To better understand, I divided the components below according to their function:

Cabinet

  • I'll use a styrofoam cooler box that I picked up (for free) from a fish shop

Heating system

  1. Heat source
    • Thermo Polyester Heating Foil Self-adhesive 12 V / DC, 12 V / AC 22 W Safety type IPX4 Ø90mm (I wanted this one but I finally order a similar one a bit cheaper)
  2. Spread the heat or cool down
    • 12V Axial Fan (caught in the fablab)

Heating Controller

  • 10K thermistor (taken from the battery of my old computer)

Brain

  • MOSFET x2 (caught in the fablab)
  • 10K resistor (I had)
  • Diode 400V (caught in the fablab)
  • arduino (I had)
  • bread board (I had)

Interface

  • Power switch (I had)
  • LCD display (caught in the fablab)
  • Button (I had)
  • Jack Adapter (I took a power plug instead in the fablab)
  • 7.5 W Power Supply (I bought in Diotronic BCN a 12V-1.5A universal power supply)

First Steps

I began by following the BioHack Academy slides I mentioned above to test each component and programming them one by one.

For visuals, check out my FabCityHub instagram stories.

Sensing the temperature

See page 11 of the slide for the schema and page 20 for the code and the tutorial (or click here)

note: the temperature was working in a reverse way for me, ~28°C for the room temp and when I touched the thermistor the temp decrease to ~22°C.. After checked the comments, I just decided to deconnect and reconnect all the wires to my breadboard with the tutorial's schema (and not the slide's schema) and then it worked in the right sense: ~19°C for the room temp and ~25°C when I touch it.

Push Buttons

See page 13 of the slide for the schema and page 20 for the code and the tutorial (or click here)

note: you have to set a second pushbutton into the code to play with 2 buttons. Here is my modified code:

// constants won't change. They're used here to set pin numbers:
const int buttonPin1 = 8;     // the number of the 1st pushbutton pin
const int buttonPin2 = 7;     // the number of the 2nd pushbutton pin
const int ledPin =  13;      // the number of the LED pin (already on the arduino)

// variables will change:
int buttonState1 = 0;         // variable for reading the pushbutton status
int buttonState2 = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState1 == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
  if (buttonState2 == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

Controlling the Fan

My fan is a EverFlow R127025BU DC 12V 0.40AMP 4-pin connector

Here is a link to know more about the 4-pin connector.

Pin Wire color Function
1 Black Ground
2 Yellow 12V
3 Green Sense (tach.)
4 Blue Control (PWM)

As I read, most fans with a separate PWM-speed-control lead are designed to run at full speed if that lead is left floating. This is a safety measure so that, if the wire comes loose, the system won't overheat due to the fan stopping.

In general, all fans designed for use in PCs use the same wiring. Starting from the black wire, they are Ground/return, +power (almost always 12V but some non-PC fans use other voltages; check the label on the fan), tachometer (wire is grounded by the fan a certain number of times per revolution, usually 2 or 4) and PWM. The PWM wire is always on the end to allow a 4-wire fan to be plugged into a 3-pin connector for either no speed control or PWM control by interrupting the +power pin.

Understand more about with this link

Now I know how to connect my fan, I can follow the instructions of page 16 of the slide and page 20 for the MOSFET code and tutorial (or click here)

LCD screen

My LCD (Liquid Crystal Display) is a Lumex LCM-S01602DTR-M. Here are the spec.

But I miss the I2C interface to follow the BHA instructions.

I found here an arduino link to control LCD displays without I2C interface. I tried but didn't work.. My LCD only shows me strange characters.

After watching this video from Programming Electronics Academy, I understood it's really difficult to have all the pins well connected. I moved my LCD in different positions on my 16-pin male header to have all pin connected and it finally works!

I then modify the code to add a second message on the LCD:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // set up the cursor position:
  lcd.setCursor(0, 0);
  // Print a message to the LCD.
  lcd.print("hello, world!");
  // set up the cursor position for the second line:
  lcd.setCursor(1, 1);
  // Print a message to the LCD.
  lcd.print("let's have fun");

}

void loop() {
  // Turn off the display:
  lcd.noDisplay();
  delay(500);
  // Turn on the display:
  lcd.display();
  delay(500);
}

Intermediate steps

It's time now to use what I learned above to build step by step the final incubator system. I'll make inputs and outputs interact together.

LCD displaying current temp

I connected the LCD and the thermistor to the arduino, following my previous corresponding steps and I wrote the code below by mixing my corresponding previous codes. My LCD is now displaying the current temperature.

#include <math.h>         //loads the more advanced math functions
#include <LiquidCrystal.h> // include the library code

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup() {            //This function gets called when the Arduino starts
  Serial.begin(9600);   //This code sets up the Serial port at 115200 baud rate

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  // Print a message to the LCD.
  lcd.print("what temp is it?");

}

double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}

void loop() {             //This function loops while the arduino is powered
  int val;                //Create an integer variable
  double temp;            //Variable to hold a temperature value
  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.println(temp);   //Print the value to the serial port

  lcd.setCursor(1, 1);
  lcd.print(temp);

  delay(1000);            //Wait one second before we do it again
}

controlling the LCD with push button

I now wanted to add push buttons to the previous step. I first run this tuto to have an example of how control LCD with push buttons. Then I wrote the code below by mixing my previous code and the code I just learned:

//##LIBRARIES/////////////////////////////////////////////////////////////

#include <math.h>          //loads the more advanced math functions
#include <LiquidCrystal.h> // include the library code for the LCD


//##DEFINE////////////////////////////////////////////////////////////////

//LCD
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//BUTTONS
const int buttonPin1 = 7;     // the number of the 1st pushbutton pin (red)
const int buttonPin2 = 8;     // the number of the 2nd pushbutton pin (black)
const int ledPin =  13;       // the number of the LED pin (already on the arduino)

//VARIABLES
int targetTemp = 28;    // Initial target temperature
int button1State = 0;   // variable for reading the pushbutton status
int button2State = 0;   // variable for reading the pushbutton status
int val;                //Create an integer variable
double temp;            //Variable to hold a temperature value


//##SETUP/////////////////////////////////////////////////////////////////

void setup() {            //This function gets called when the Arduino starts
  Serial.begin(9600);     //This code sets up the Serial port at 9600 baud rate

  pinMode(ledPin, OUTPUT);    // initialize the LED pin as an output:
  pinMode(buttonPin1, INPUT); // initialize the pushbutton pin as an input:  
  pinMode(buttonPin2, INPUT); // initialize the pushbutton pin as an input:
}

double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}


//##LOOP////////////////////////////////////////////////////////////////////

void loop() {             //This function loops while the arduino is powered

  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.println(temp);   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again

  button1State = digitalRead(buttonPin1); // Read the state of the pushbutton value
  button2State = digitalRead(buttonPin2);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("press red");
  lcd.setCursor(1, 1);
  lcd.print("or black");

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (button1State == HIGH) {
    // print current temp on LCD:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("current temp:");
    lcd.setCursor(1, 1);
    lcd.print(temp);
  }
  if (button2State == HIGH) {
    // print target temp on LCD:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("target temp:");
    lcd.setCursor(1, 1);
    lcd.print(targetTemp);
  }
}

Then, I went a step further by adding to my pushbuttons the function to increase or decrease the target temperature by using if (button1State == HIGH) {targetTemp = targetTemp+1;} and if (button2State == HIGH) {targetTemp = targetTemp-1;} in my loop code.


//##LOOP////////////////////////////////////////////////////////////////////

void loop() {             //This function loops while the arduino is powered

  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.println(temp);   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again

  button1State = digitalRead(buttonPin1); // Read the state of the pushbutton value
  button2State = digitalRead(buttonPin2);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
    lcd.setCursor(0, 0);
    lcd.print("Current");
    lcd.setCursor(10, 0);
    lcd.print(temp);
    lcd.setCursor(15, 0);
    lcd.print("C");
    lcd.setCursor(0, 1);
    lcd.print("Target");
    lcd.setCursor(10, 1);
    lcd.print(targetTemp);
    lcd.setCursor(15, 1);
    lcd.print("C");

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (button1State == HIGH) {
    targetTemp = targetTemp+1;
    // print on LCD:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("set target temp:");
    lcd.setCursor(0, 1);
    lcd.print(targetTemp);
  }
  if (button2State == HIGH) {
    targetTemp = targetTemp-1;
    // print on LCD:
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("set target temp:");
    lcd.setCursor(1, 1);
    lcd.print(targetTemp);
  }
}

controlling the heating source with the temp

Due to CO-VID19 my heating pad is stuck somewhere between China and here. So I did a new order out of amazon, on BricoGeek which is based in Spain. The only heating system I found there is a Thermoelectric coolers (TEC or Peltier) that can be used to either warm something up or cool something down because it creates a temperature differential on each side. One side gets hot and the other side gets cool (and you can also take advantage of a temperature differential to generate electricity). You can find all the spec and info directly on Sparkfun

It is also recommended to use a heat sink on the hot side of the module otherwise it can get too hot to comfortably touch. So I bought one aswell on BricoGeek.

The step now is trying to control the fan and the heating source with the thermistor.

It was more complicated than expected.. then I decided to try the final code of the BHA first, just to see. I ran the BHA code by adapting the numbers of my pin and some other stuff like only analog temp sensor and adapt the LCD screen code, and it works! Not completely like I wanted because the fan is always working and it works half way when the heating pad is turning on.

Another thing is that the wires that connect the 12V power supply to the arduino and to the heating pad and the fan got very hot when the heating pad was heating. So I feel I have to go a step back and test the TEC by itself.

The problem with the TEC is that is using a lot of juice (till 60W!!). On the Sparkfun's documentation page, there is an arduino code file to slowly ramp up the power flowing through the MOSFET to run the TEC.

I tried by connecting my arduino and the TEC together with a MOSFET trought my breadboard like this schema below.

by ramping up the power into the serial monitor up to 50% (like explained on the arduino file) I measured with my multimeter 11,5V and 0,75A (=8,5W) instead of 11,5V and 2,15A (=25.8W) without the arduino program.

My boyfriend, who is doing the Fab Academy at the time of my writing, decided to assign his "output devices assignement" by giving me a hand. Lucky me!

peltier https://theplantbot.com/introduction-to-peltier-cooling/ https://www.trentfehl.com/projects/chamber/ https://hackaday.com/2020/01/08/engineering-your-way-to-better-sourdough-and-other-fermented-goods/

Fail

I wanted to continue where it happened, but I obviously made a wrong move and I can no longer use my arduino.. the message stk500_recv(): programmer is not responding appears when I try to load the code from my arduino IDE to my arduino Uno. After some readings on forum.arduino, stackoverflow and stackexchange, it seems to mean that something wrong is happening before the flashing actually begins.

It can be on different level and I can check from hardware to software (low level to high level):

  • if the cable and/or connectors does not have microcuts;
  • if no solder points are short circuiting (i.e. touching something metallic around), that means:
    • if there is no short circuit on the PCB between Rx and Tx (usually pins 1 and 0);
    • if there is no contact with a metallic element below the board, or tiny bits between a component's legs (like the FTDI, the ATmega chip or any other);
  • if the ATmega chip is not out of power (GND/VCC shortcut or cut or VCC input being dead…);
  • if the 1 and 0 pins of the Arduino are not being used by some shield or custom design (/!\ does not apply to the Leonardo as it has independent USB handling);
  • if the USB to UART converter does not have a problem (FTDI on older Duemilanove or ATmega16U2 on newer Arduino Unos);
  • if the ATmega328 chip is fried or wrongly installed;
  • if the bootloader has been overwritten or is failing;
  • if the right baudrate is applied for entering the bootloader;
  • if the right settings are set for the target microcontroller and Board;

If the boot loader has been crashed, the solution coulb be to reload the bootloader.

In any case, I think the problem comes from the peltier because it could use till 60W and my power supply goes to max 18W. So I guess I had a short while prototyping with the breadboard which burns one of the component of the arduino.

Created 20/02/2020

Updated 20/02/2020