Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Is this PID PIC project working correctly ?

Not open for further replies.


Advanced Member level 3
Aug 19, 2015
Reaction score
Trophy points
Activity points

I have used PIC16F877A @ 4 MHz external crystal. I have used Dany's PID Library posted at libstock.

The mikroC PRO PIC library contains only 3 functions and the mikroPascal PRO PIC library contains 5 functions. So, I have ported mikroPascal PRO PIC PID Library to mikroC PRO PIC.

I want to know have I successfully ported the PID Library to C ?

If the mikroPascal PRO PIC library (.mkpg) file is installed using the mikroE Package Manager then it creates a Packages\PID Library\Examples folder in the Compiler folder. It contains two zipped files which are examples of using the Library. I have used the code of one of the examples to test the Library but I am not sure whether the Library has been successfully ported to C or not.

I am posting the screenshot (Proteus simulation) of the project. Is the values it is showing correct ?


  • PID Test.rar
    94.6 KB · Views: 118
  • PID Test.png
    PID Test.png
    32.5 KB · Views: 133

I am posting the screenshot (Proteus simulation) of the project. Is the values it is showing correct ?

No one is able to give some advice without downloading the whole project, unless you specify eactly which functions are that. Moreover, you had not mentioned what numerical values are that, from what plant model, as well what values are expected.

There are only 5 functions and it is in the main project file (.c) only. Here I am posting the mikroPascal code if anybody can have a look at the original Pascal code.

I am attaching both the PID Library (which contains 5 functions) [mikroPascal Code] and also the Pascal test project. The Pascal test project code contains the values the program outputs but I am not getting the values mentioned in the code.

It is displaying all 0 values as -0 (minus zero). Don't know why. The numerical values obtained are same as mentioned in the TestPID code.


  • PID_Lib.rar
    1.9 KB · Views: 124
    1.5 KB · Views: 114

Hi pic_programmer, I compared your code with the Pascal code, and I can find no differences between them (apart from the different syntax of course). So, it should work.
I will try to do a test with your C version as soon as possible (provided the code is not too large, I have no licence...).

Kind regards,

- - - Updated - - -

Hi PIC Programmer,
about the zero values shown as '-0' I found the following:

After Execution of this statement strange happens:
// --- calculate total ---
    RetVal = ErrValue + Controller.PID_Integrated - DiffValue; // mind the minus sign!!!
Looking in the debugger with all types set to float everything looks fine:

But, when looking in hexadecimal (or binary) the value of RetVal shows a non zero value. This is the reason why the zero outcomes are shown as '-0' by FloatToStr:
Capture26-8-2015-12.05.45.jpgSee the value of "RetVal" at the bottom of the image.
RetVal shows a non zero value.
Not actually non-zero, just -0.0, a zero with sign bit set. You can either consider it as an ambiguity brought up by the float format or a mikroE float library bug, whatever you prefer.

Ok. Dany and FvM. I will see if I can make any changes to the code so that the value of C version matches with the Pascal version.


This is my new project. It is PID Temperature Controller. As it is related to the PID and also as I am using the same PID library used in post #1 of this thread, I am posting this new question here.

See the attached file. It contains mikroC PRO PIC project and Proteus file.

It is not working, but why ?

In the Proteus file I have set Temperature coefficient of OVEN to 10mV/degree C, same as LM35 and the ouput of OVEN is connected to ADC input. You can see that the SSD displays 27 as the temperature. This is because the ambient temperature of the oven is set to 27. AC mains voltage is 220V 50 Hz.

In the
function, I have only used Kp. Ki and Kd are not used as of now. My understanding is this.

If actual temperature is 0 degree C and set value is 150 degree C then proportional error = 150 - 0 = 150 dgeree C and I have used proportional error multiplier as 1, So,

proportional error * proportional error multiplier = 150 * 1 = 150.

In the
function, I have to set MinOutput and MaxOutput value to 0 and 150 that is temperature and (setVal - temperature). Right ?

In the
function, I am passing the right arguments that is setVal and temperature.

I want to know how to make up the arduino map() function. My idea is (as of now whitout using Ki and Kd) to take the output of the PID system and using Arduino map() function scale it to 0 to 32 (because there are 32 steps in the TRIAC firing) and control the heater power.

If say actual temperature is 0 degree C and set value is 150 degree C then proportional error = 150. So this 0 to 150 range has to be converted to 0 to 32 value using Arduino map() function and if value is 150 then the value becomes 32 and so TRIAC fires after 32 steps that is near the end of the half AC cycle because

AC frequency is 50 Hz. T = 20 ms. T/2 = 10 ms.

Instead of taking 10 ms, I have taken 9 ms because AC mains frequency may drift. So 9 ms / 32 = 218 us.

So if proportional error is 150 then it is mapped to 32 and so the TRIAC fires after 32 * 218 us = 9 ms. So the AC power to heater will be very less.

So, my question is how to make up the Arduino map() function, that is what values I have to pass to the functions ?

broken link removed

- - - Updated - - -

Have I done this correctly ? I have only used Kp in the PID system. Later I will implement Kp, Ki and Kd. See attached file (LM35 version). At 150 degree C the power to heater is almost nil and at 0 degree C the power to heater is max. In code I have set the value of setVal variable to 150 instead of using buttons to set the setVal (set point).

Have I used the Arduino map() function correctly ?

broken link removed


  • PIC16F877A PID Temperature Controller.rar
    207.9 KB · Views: 110
  • PID Temperature Controller.png
    PID Temperature Controller.png
    125.1 KB · Views: 318
  • PID Temperature Controller.png
    PID Temperature Controller.png
    123 KB · Views: 169
  • PIC16F877A PID Temperature Controller LM35.rar
    211.7 KB · Views: 106
Last edited by a moderator:

It is not working, but why ?

As far as I'm aware of, you have already some experience with microcontrollers.

I think it's time to learn elementary debugging methods, e.g. tracing code execution line by line in a simulator or hardware debugger and find out where the results are deviating from expected behaviour.

Although you may be able find the errors by a thorough code review, debugging techniques usually show it faster.

Did you know that basic source code debugging is even possible in Proteus?

Ok FvM. I will try printing the PID values on I2C 20x4 LCD and see if all values are correct.

Attached images are related to the LM35 based PID Temperature Controller project.

broken link removed


  • 0 degree centigrade.png
    0 degree centigrade.png
    125 KB · Views: 158
  • 75 degree centigrade.png
    75 degree centigrade.png
    124.7 KB · Views: 152
  • 150 degree centigrade.png
    150 degree centigrade.png
    122.8 KB · Views: 161
Last edited by a moderator:

Hi PIC Programmer,

I hope you are aware of the fact that there is no galvanic mains isolation between on one hand the PIC and LCD and buttons and on the other hand the mains circuit?

- - - Updated - - -

Hi Pric programmer,
You did send me a link with another project, but I think also there there is a problem with galvanic isolation, while in both the triac drive and the zero crossing detector optocouplers are present to guarantee galvanic isolation. I marked in red what has to change to make it right... (assumed you actaully wanted galvanic isolation between PIC and mains...)

@ DanyR

I will take care of the ZCD circuit. That circuit I just used for Proteus simulation. In hardware the mains will be completely isolated from PIC.

In proteus I have used the OVEN model for heater. How to set its properties so that the temperature of the Oven rises quickly from 27 to 150 degree C in say 20 seconds ? I have set it to give output similar to LM35. I want the temperature of the Oven to not rise above 150 degree C. In Oven property it is by default set that it is 1.2KW heater.

- - - Updated - - -

I think my calculations are wrong. Dany said in email that the MinOutput and MaxOutput values for the Init_PID() function have to be symmetrical like -100 and 100.

He said that if values are -10 and 10 and if I am using a 10 bit ADC with 10 mV/degree C and 5V Vref then Kp value is 10/2 = 5.

Does that mean that if I have a similar ADC setupt and my MinOutput and MaxOutput values are -100 and 100 (-100 = TRIAC fully ON, 100 = TRIAC fully OFF)

Then my Kp = 100 / 2 = 50 (50 is the Proportional error multiplier) ?

If actual temperature is 20 and setpoint is 40 then 40 - 20 = 20 and 20 into 50 = 1000. Is this correct ? I need a system such that it has to quickly rise the temperature of the heater so that setpoint is quickly reached and once setpoint is reached it has to maintain the power to heater such that the water in heater remains at setpoint.

According to DanyR if MinOutput and MaxOutput of Init_PID() function are -100 and 100 then the output of PID_Calculate() function can vary between -100 and 100.

In Proteus there is Oven model. How to calculate its gain ? Its power rating is 1.2KW.

Should use Pout max / Pin to calculate the gain ? If not, what is the formula to calculate heater gain ?
Last edited:

Does that mean that if I have a similar ADC setupt and my MinOutput and MaxOutput values are -100 and 100 (-100 = TRIAC fully ON, 100 = TRIAC fully OFF)

Hi pic.programmer, I did have a look into the original Pascal code, and the comments for "PID_Calculate" say:
// Functionresult: PID function of (SetPoint, InputValue) of "Controller",
// a positive value means "InputValue" is too low (< SetPoint), the process should take action to increase it
// a negative value means "InputValue" is too high (> SetPoint), the process should take action to decrease it
This means that -100 should steer the triac fully OFF, while
+100 should steer the triac fully on.
Sorry for the misunderstanding. It is possible that I've sent you some mails with this thing reversed. :shock:
Not open for further replies.

Part and Inventory Search

Welcome to