Moving away from arduino- best uProcessor for making PID device?

Discussion in 'Embedded Systems and Microcontrollers' started by camjerlams, Oct 5, 2016.

  1. camjerlams

    Thread Starter Member

    Dec 23, 2012
    56
    1
    Hi,
    I'm an amateur teaching myself some electronics. Ive recently made a plant waterer with an arduino using a closed loop control, now I'd like to try and make a PID controller for a small ceramic heating element but I'd like to move away from the arduino to reduce size and teach myself a few things.

    I have an ATMega 328 with a crystal oscillator that I thought I could program, then I could design my own PCB and case for this device and have them printed which would be more pro than just slapping an arduino inside a waetherproof box as I have done with the plant thing.

    I have never programmed a uProcessor from scratch so before jummping in i thought I'd ask what is the best/most popular for something like this?
    Or to put it another way- if I wanted to easily make a prototype device for mass production what uProcessor would be best?

    Any links to tutorials and whatnot are very welcome.

    Cheers!
     
  2. dannyf

    Well-Known Member

    Sep 13, 2015
    1,824
    364
    Any MCU is the best MCU for pid.
     
    camjerlams likes this.
  3. Sensacell

    Well-Known Member

    Jun 19, 2012
    1,132
    267
    cmartinez and camjerlams like this.
  4. blocco a spirale

    AAC Fanatic!

    Jun 18, 2008
    1,440
    368
    An Arduino Nano/uno/Pro Mini is really nothing more than a ATMega 328 so you could just develop your project using an Arduino board and IDE and then load the program into an ATMega 328 fitted to your own PCB.
     
    djsfantasi and camjerlams like this.
  5. camjerlams

    Thread Starter Member

    Dec 23, 2012
    56
    1
    Could one sell a device running on Arduino IDE? It's not that I intend to, I just want to know that I can make something that is entirely mine.
     
  6. camjerlams

    Thread Starter Member

    Dec 23, 2012
    56
    1
    Nevermind I just looked it up and that is totally fine if someone wants to do that, hence all the arduino compatible stuff on the market.
    Thanks for the reply :).
    https://www.arduino.cc/en/Main/FAQ
     
  7. jayanthd

    Member

    Jul 4, 2015
    274
    29
    If you can use PIC, AVR, dsPIC, PIC24, PIC32 then I can provide you a PIC library. it will solve 95% of your problem. All you have to do is calculate Kp, Ki and Kd values and use it to control your Heater. Heater will be AC and you need a TRIAC to control the power to it. You need a ZCD circuit also. You need to detect the ZC and then after the required delay you have to fire the TRIAC.
     
    camjerlams likes this.
  8. NorthGuy

    Active Member

    Jun 28, 2014
    604
    121
    If you want to sell something, it's certainly be cheaper to produce with small MCU (such as PIC12) on small PCB.
     
    cmartinez and camjerlams like this.
  9. camjerlams

    Thread Starter Member

    Dec 23, 2012
    56
    1
    OK sure I'd like to have a look at that. So the TRIAC provides square wave AC for the element? I want to make it battery powered.
     
  10. tranzz4md

    Member

    Apr 10, 2015
    139
    28
    Battery powered? So, that'd be isolated from the power circuit for the heater? Heaters need POWER.

    The triac won't be making any square waves, not by itself at least. You may of course be thinking of a very, very small heater and the whole thing being battery powered, for a short period of time.
     
    camjerlams likes this.
  11. tranzz4md

    Member

    Apr 10, 2015
    139
    28
    Go googling. Use lotsa buzz words

    Microcontroller, Arduino etc. then keep clicking links. Probably even Wiki Arduino or ATmega.
     
    camjerlams likes this.
  12. R!f@@

    AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    Battery powered PID controlled heater does not require zero crossing and a triac. One properly rated MOSFET will do.
    If jayanthd provides you with a PID library than you can by all means make it quite easily.
     
    camjerlams likes this.
  13. jayanthd

    Member

    Jul 4, 2015
    274
    29
    The original library was written by DanyR at mikroe forum. It was in mikroPascal. I had converted it to mikroC. I am attaching the file which I made looking at the mikroPascal code.

    Here is the link for DanyR's libraries. I just check it now and he also has made a mikroC version.

    You can use the library with any C Compiler.

    http://libstock.mikroe.com/projects/view/161/pid-library

    For .mpkg files you need mikroE's free Package Manager tool to extract and install.

    If your code is small ( < 4 KB ) then you can use demo version of mikroElektronika's mikroC PRO PIC or any mikroE Compiler.


    Here is the code which I ported from mikroPascal.

    Code (C):
    1.  
    2. // ---------------------------------------------------------- //
    3. // ---- PID library with fixed calculation time interval ---- //
    4. // ---------------------------------------------------------- //
    5.  
    6. // D. Rosseel
    7. // Original: 27-09-2011
    8. // Latest update: 31-10-2011
    9.  
    10. /* History:
    11.   27-09-2011: Original Version.
    12.   04-10-2011: Added the "Integration Improvement" mechanism. This mechanism prevents overshoot/ringing/oscillation due to integration.
    13.   05-10-2011: Reduced code size a little, made "Integration Improvement" easier to read.
    14.   12-10-2011: More than one PID controller can operate now in one program with the usage of "PIDController" variables.
    15.   31-10-2011: Added the "Differentiation Improvement" mechanism. This mechanism prevents unnecessary delays due to differentiation.
    16. */
    17.  
    18. // Documentation: http://en.wikipedia.org/wiki/PID_controller/ and http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
    19.  
    20.  
    21. #define BOOL unsigned char
    22. #define TRUE 1
    23. #define FALSE 0
    24.  
    25. struct PID {
    26.        double PID_Kp, PID_Ki, PID_Kd;
    27.        double PID_Integrated;
    28.        double PID_Prev_Input;
    29.        double PID_MinOutput, PID_MaxOutput;
    30.        BOOL PID_First_Time, PID_Int_Improvement, PID_Diff_Improvement;
    31.        double PID_Prev_AbsError;
    32. } Controller;
    33.  
    34. void Init_PID(double Kp, double Ki, double Kd, double MinOutput, double MaxOutput);
    35. // Initialises the PID engine of "Controller"
    36. // Kp = the "proportional" error multiplier
    37. // Ki = the "integrated value" error multiplier
    38. // Kd = the "derivative" error multiplier
    39. // MinOutput = the minimal value the output value can have (should be < 0)
    40. // MaxOutput = the maximal value the output can have (should be > 0)
    41.  
    42. void Set_PID_Int_Improvement(BOOL On_);
    43. // Switches on or off the "Integration Improvement" mechanism of "Controller". This mechanism prevents overshoot/ringing/oscillation
    44. // due to integration. To be used after "Init_PID", which switches off the mechanism for compatibility reasons.
    45.  
    46. void Set_PID_Diff_Improvement(BOOL On_);
    47. // Switches on or off the "Differentiation Improvement" mechanism of "Controller". This mechanism prevents unneccessary correction
    48. // delay when the actual value is changing towards the setpoint.
    49. // To be used after "Init_PID", which switches off the mechanism for compatibility reasons.
    50.  
    51. void Reset_PID();
    52. // Re-initialises the PID engine of "Controller" without change of settings
    53.  
    54. double PID_Calculate(double Setpoint, double InputValue);
    55. // To be called at a regular time interval (e.g. every 100 msec)
    56. // Setpoint: the target value for "InputValue" to be reached
    57. // InputValue: the actual value measured in the system
    58. // Functionresult: PID function of (SetPoint - InputValue) of "Controller",
    59. //   a positive value means "InputValue" is too low (< SetPoint), the process should take action to increase it
    60. //   a negative value means "InputValue" is too high (> SetPoint), the process should take action to decrease it
    61. // Timing: A call to this routine costs 140 uS time (P18F2550 running at 48 Mhz)
    62.  
    63.  
    64. void Reset_PID() {
    65.     Controller.PID_Integrated    = 0.0;
    66.     Controller.PID_Prev_Input    = 0.0;
    67.     Controller.PID_Prev_AbsError = 0.0;
    68.     Controller.PID_First_Time    = TRUE;
    69. }
    70.  
    71. void Set_PID_Int_Improvement(BOOL On_) {
    72.   Controller.PID_Int_Improvement = On_;
    73. }
    74.  
    75. void Set_PID_Diff_Improvement(BOOL On_) {
    76.   Controller.PID_Diff_Improvement = On_;
    77. }
    78.  
    79. void Init_PID(double Kp, double Ki, double Kd, double MinOutput, double MaxOutput) {
    80.     Controller.PID_Kp               = Kp;
    81.     Controller.PID_Ki               = Ki;
    82.     Controller.PID_Kd               = Kd;
    83.     Controller.PID_MinOutput        = MinOutput;
    84.     Controller.PID_MaxOutput        = MaxOutput;
    85.     Controller.PID_Integrated       = 0.0;
    86.     Controller.PID_Prev_Input       = 0.0;
    87.     Controller.PID_Prev_AbsError    = 0.0;
    88.     Controller.PID_Int_Improvement  = FALSE;
    89.     Controller.PID_Diff_Improvement = FALSE;
    90.     Controller.PID_First_Time       = TRUE;
    91. }
    92.  
    93. char Sign(double Value) {
    94.   if(Value >= 0)return 1;  // positive
    95.   else return 0;           // negative
    96. }
    97.  
    98. double AbsReal(double val1) {
    99.   if(Val1 < 0)return -Val1;
    100.   else return Val1;
    101. }
    102.  
    103. double Limit(double *Value, double MinOutput, double MaxOutput) {
    104.   if(*Value < MinOutput)*Value = MinOutput;
    105.   else if(*Value > MaxOutput)*Value = MaxOutput;
    106. }
    107.  
    108. double PID_Calculate(double Setpoint, double InputValue) {
    109.     double Err, ErrValue, DiffValue, ErrAbs, RetVal;
    110.  
    111.     Err = SetPoint - InputValue;
    112.     if(Controller.PID_Diff_Improvement)ErrAbs = AbsReal(Err);
    113.  
    114.     // --- calculate proportional value ---
    115.     ErrValue  = Err * Controller.PID_Kp;
    116.  
    117.     // --- PID Int Improvement ---
    118.     if(Controller.PID_Int_Improvement)
    119.           if(Sign(Err) != Sign(Controller.PID_Integrated)) {
    120.                  Controller.PID_Integrated = 0.0;
    121.           }
    122.  
    123.     // --- Calculate integrated value ---
    124.     Controller.PID_Integrated = Controller.PID_Integrated + (Err * Controller.PID_Ki);
    125.     // limit it to output minimum and maximum
    126.     Limit(&Controller.PID_Integrated, Controller.PID_MinOutput, Controller.PID_MaxOutput);
    127.  
    128.     // --- calculate derivative value ---
    129.     if(Controller.PID_First_Time) {
    130.       // to avoid a huge DiffValue the first time (PID_Prev_Input = 0)
    131.       Controller.PID_First_Time    = FALSE;
    132.       Controller.PID_Prev_Input    = InputValue;
    133.       Controller.PID_Prev_AbsError = 0.0;
    134.     }
    135.  
    136.     DiffValue = (InputValue - Controller.PID_Prev_Input) * Controller.PID_Kd;
    137.     Controller.PID_Prev_Input = InputValue;
    138.  
    139.     // --- PID Diff Improvement ---
    140.     if(Controller.PID_Diff_Improvement) {
    141.       if(ErrAbs < Controller.PID_Prev_AbsError)DiffValue = 0.0; // error becomes smaller, stop differentiation action
    142.       Controller.PID_Prev_AbsError = ErrAbs;
    143.     }
    144.  
    145.     // --- calculate total ---
    146.     RetVal = ErrValue + Controller.PID_Integrated - DiffValue; // mind the minus sign!!!
    147.     // limit it to output minimum and maximum
    148.     Limit(&RetVal, Controller.PID_MinOutput, Controller.PID_MaxOutput);
    149.  
    150.     return RetVal;
    151. }
    152.  
    153. double output;
    154.  
    155. void main() {  
    156.        
    157.      while(1) {  
    158.        
    159.           Init_PID(2,0,0, -100, 100);  // Init_PID(double Kp, double Ki, double Kd, double MinOutput, double MaxOutput)
    160.  
    161.           output = PID_Calculate(20, 20);  // double PID_Calculate(double Setpoint, double InputValue)
    162.      }
    163. }
    164.  
     
    Last edited: Oct 6, 2016
    camjerlams likes this.
  14. jayanthd

    Member

    Jul 4, 2015
    274
    29
    For battery powered Heater you have to use PWM with PID and ofcourse a Power Mosfet is needed. Choose a Logic gate Power Mosfet with very low Rds(on).
     
    camjerlams likes this.
  15. jayanthd

    Member

    Jul 4, 2015
    274
    29
    What is the voltage applied to heater ? Are you going to use a 12 V or 24 V 140 Ah Lead-Acid battery ?
     
    camjerlams likes this.
  16. camjerlams

    Thread Starter Member

    Dec 23, 2012
    56
    1
    I haven't decided but I think I'll get an NiMH, was thinking 2 of these at around 7v each and using a 12V ceramic element.
     
Loading...