Hackster will be offline on Monday, September 30 from 8pm to 10pm PDT to perform some scheduled maintenance.
salhar1
Published © GPL3+

Micro-Thermostat

Tiny thermostat based on the mini-thermostat project. Code and schematics included.

IntermediateShowcase (no instructions)4 hours909
Micro-Thermostat

Things used in this project

Hardware components

Adafruit Trinket - Mini 3.3 V
×1
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×1
10 K NTC Thermistor
×1
Power MOSFET N-Channel
Power MOSFET N-Channel
×1
Perfboard (prototype paper PCB)
×1

Software apps and online services

Adafruit Windows Driver
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Circuit schematic

Code

Temperature controller

C/C++
Includes:
- thermistor code for temperature readout
- code for controlling heater input
- basic PID controller
//Definitions for pins of Trinket 3.3V
  //AnalogWrite()
     #define AW_PB0 0
     #define AW_PB1 1
     #define AW_PB4 4    
  //AnalogRead()
     #define AR_PB2 1
     #define AR_PB3 3
     #define AR_PB4 2
  //Digital pins
     #define D_PB0 0
     #define D_PB1 1
     #define D_PB2 2
     #define D_PB3 3
     #define D_PB4 4

// variables and definitions
      //Important parameter, set to match environment
          const int dt = 500; // [ms] time constant in milliseconds (controller clock rate = 1/(dt/1000) [Hz])
          #define SetTemp 62.8 // [degC] set temperature in DegC
          #define MinTemp 20 // [degC] minimum expected temperature (needed for rescaling inputs)
          #define MaxTemp 65 // [degC] maximum allowed temperature, over which heater is turned off (needed for rescaling inputs)
          int SetTime = 1800; // [s] timer in seconds, if reached, running stops [Default: 1800]

      //I/O pins - don't edit unless replaced
          #define thermistorPin AR_PB4 //number of thermistor pin
          #define FETPin AW_PB1 //the number of the MOSFET pin
		  //#define LEDPin ? //the number of the LED pin

      //control parameters - editing not recommended     
          double K_P_ctrl = 15; //proportional gain
          double K_I_ctrl = 0; //integral gain (set to lower values i.e. 10^-3)
          double K_D_ctrl = 0; //derivative gain
          
// including headers
  #include <math.h>
  
//Inititalization
    //target temperature reached?
       bool bInRange = 0;

    //ticks per ms
       int TicksPerMS = floor(1000/dt);

    //Initialize PID variables:
       float previous_error = 0;
       float s_integral = 0;   

//Thermistor code - hard-coded constants for generic 10K NTC thermistor
    double Thermistor(int RawADC) {
      double Temp;
      Temp = log(10000.0*((1024.0/RawADC-1))); 
      Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
      Temp = Temp - 273.15;            // Convert Kelvin to Celcius
      return Temp;
    }

//PID controller code
    void Control_PID(double iTemp){
        
      //Overheat protection
          if(iTemp>MaxTemp){
            analogWrite(FETPin, 0);
            return;
          }
        
      //In range? If in range, do something (maybe turn on LED?)
          if((iTemp) >= SetTemp){
            if(bInRange==0){
              //TODO: add code what to do when in range
              //digitalWrite(LEDPin, HIGH); 
              bInRange=1;
            }
          }else{
            if(bInRange==1){
              //TODO: add code what to do when out of range 
              //digitalWrite(LEDPin, LOW); 
              bInRange=0;
            }
          }
          
        
        //PID subroutine
          float err = SetTemp - iTemp;
          s_integral += err*dt;
          float s_derivative = (err - previous_error)/dt;
          int U_in_ctrl = (K_P_ctrl*err + K_I_ctrl*s_integral + K_D_ctrl*s_derivative)/(MaxTemp-MinTemp)*255;
          previous_error = err;
                 
          
        // put voltage to output          
            if (U_in_ctrl<=255){
               if (U_in_ctrl > 0){
                  analogWrite(FETPin, U_in_ctrl);
               }           
               else
               {
                  analogWrite(FETPin, 1);
               }
            }
            else{
               analogWrite(FETPin,255);
            }                   
    }

void setup() {
    pinMode(FETPin, OUTPUT);
  
    //rescale timer according to dt
    SetTime = SetTime * TicksPerMS;    
}

void loop() { 
  //Take a temperature reading and display it 
    double Temp = double(Thermistor(analogRead(thermistorPin)));
              
  //Call controller algorithm 
    Control_PID(Temp); // call controller algorithm
    
  //Timer ticking (countdown)
    if (SetTime>0){
        SetTime--;
        // if zero reached
        if (SetTime==0){
          while(1) {
            //loop until disconnected - you might want to flash the LED or something...
            digitalWrite(FETPin, LOW);
            delay(dt);
          } 
        }
    }
    
   //wait dt before next cycle
      delay(dt); 
}

Credits

salhar1

salhar1

0 projects • 5 followers
Thanks to Adafruit and Adafruit.

Comments