News:

Let's find out together what makes a PIC Tick!

Main Menu

PID_MAX6675

Started by Murat Atakan, Jul 16, 2024, 10:58 AM

Previous topic - Next topic

Murat Atakan

PID proton was written in version 3.5.2.7.
It works very well.
There is no problem compiling it in different versions.
but it doesn't work properly.
Positron gives an error during compilation in version 4.0.4.2-1.1.1.8.
It gives error TMR1H.
I couldn't fix this error, I'm waiting for your help.

Maxi

#1
add "Declare HPWM2_Pin PORTC.4" your code
and change "Symbol TMR1 = TMR1L.Word" > "Symbol TMR11 = TMR1L.Word"

edit:
but have some another problem too
circuit not working well

Murat Atakan

Thanks for your reply Maxi.
Even though I did what you said
The latest version of positron gives the same errors.

Pepe

#3
Look #10

Pepe

#4
look #10

Murat Atakan

pepe program is out of version 3.5.2.7
It doesn't work properly when compiled.
When we press and release the button next to the heater
the heat goes up and down.
This does not happen in my zip file.
I just bought the new version of Positron. When I compiled the working system here, it stopped working.

Maxi

Quote from: Murat Atakan on Jul 16, 2024, 01:07 PMpepe program is out of version 3.5.2.7
It doesn't work properly when compiled.
When we press and release the button next to the heater
the heat goes up and down.
This does not happen in my zip file.
I just bought the new version of Positron. When I compiled the working system here, it stopped working.

Exactly, that's what I meant. It compiles, but the programme doesn't run properly.

trastikata

This line here:

err = task - temp << 4

Break it in two and try again:

temp = temp << 4
err = task - temp

top204

#8
There is a section of code in the .bas file that did not make sense and will cause anomalies:

task = ERead 0                           
Kp = ERead 4
Td = ERead 8
Ti = ERead 12
t_step = ERead 16
t_pwm = ERead 18
Mode = ERead 19
PR2 = ERead 20

But the code has the Edata table commented out, so the variables will be filled with $FF values (empty EEPROM cells), and the multi-byte variables will be filled with absolutely huge values:

'EData dword 2904,float 140,float 15,float 123,_  EEPROM
'      word 300,byte 1,byte 1,byte 19

When they are uncommented, the program seems to work as it should. I have re-formatted and tweaked the code so it is a bit easier to follow and a bit more efficient, and it is listed below:

'
' PID_MAX6675 Positron8 code
'
    Device = 16F876A
    Declare Xtal = 20
    On_Hardware_Interrupt GoTo ISR_Handler
'
' Setup the LCD pins
'
    Declare LCD_Type = Alphanumeric
    Declare LCD_DTPin = PORTB.4
    Declare LCD_ENPin = PORTB.2
    Declare LCD_RSPin = PORTB.1
    Declare LCD_Interface = 4
    Declare LCD_CommandUs = 2000
    Declare LCD_DataUs = 50
    Declare LCD_Lines = 2
'
' Setup the CCP2 pin
'
    Declare CCP2_Pin = PORTC.1
'
' Setup the peripheral pins
'
    Symbol CLK_Pin   = PORTA.1
    Symbol DOUT_Pin  = PORTA.2
    Symbol CS_Pin    = PORTA.3

    Symbol TRIAC_Pin = PORTC.4
    Symbol Enc_Pin1  = PORTA.0
    Symbol Enc_Pin2  = PORTB.0
    Symbol Service_Button = PORTA.4
    Symbol Run_Button = PORTA.5
'
' Create some variables
'
    Dim fKp       As Float
    Dim fTd       As Float
    Dim fTi       As Float
    Dim fKp1      As Float
    Dim fTd1      As Float
    Dim fTi1      As Float
    Dim dTemp     As SDword
    Dim dTask     As SDword
    Dim dErr      As SDword
    Dim dLast_Err As SDword
    Dim dPWR      As SDword
    Dim dI        As SDword
    Dim dInteg    As SDword
    Dim dD        As SDword
    Dim dDiff     As SDword
    Dim wKukla    As Word
    Dim wLCD      As Word
    Dim wT_Step   As Word               ' PID mS
    Dim bT_PWM    As Byte
    Dim bChoice   As Byte
    Dim bMode     As Byte               ' P, PD, PI, PID, RELAY
    Dim tRun      As Bit
    Dim tEFlag    As Bit                ' EEPROM
    Dim tMenuFlag As Bit
'
' Create some 16-bit SFRs
'
    Dim wTMR1_SFR As TMR1L.Word
    Dim wCCP1_SFR As CCPR1L.Word
'
' Create data in on-board EEPROM
'
EE_Task   EData Dword 2904
EE_Kp     EData Float 140
EE_Td     EData Float 15
EE_Ti     EData Float 123
EE_T_Step EData Word 300
EE_T_PWM  EData Byte 1
EE_Mode   EData Byte 1
EE_PR2    EData Byte 19

'-------------------------------------------------------------------------------
' The main program starts here
'
Main:
   Setup()
Cont:
    Service()
    fKp1 = fKp
    fTd1 = fTd
    fTi1 = fTi

    fKp = fKp / 10
    fTd = fTd / 10
    fTi = fTi / 10

    fTd = fTd * 1000 / wT_Step          ' PID
    fTi = fTi * 1000 / wT_Step

    Cls
    Print At 1, 1, "Set=", Dec3 dTask >> 3,
          At 1, 10, "Tmp=",
          At 2, 1, "Pwr=",
          At 2, 12, "Stop"

    PinHigh CS_Pin
'
' PID
'
    Do
        If Service_Button = 1 Then
            If tRun = 0 Then
                fKp = fKp1
                fTd = fTd1
                fTi = fTi1
                Service()
                Goto Cont
            EndIf
        EndIf
        PinClear CS_Pin
        SHIn DOUT_Pin, CLK_Pin, 0, [dTemp \ 15]
        PinSet CS_Pin
        dTemp.15 = 0
        dTemp.14 = 0
        dTemp.13 = 0
        dTemp.12 = 0

        If dTemp > 8000 Then
            INTCONbits_GIE = 0
            PinLow TRIAC_Pin
            Cls
            Print At 1, 1, "Thermocouple Err"
            Do
                Sound PORTC.3, [126, 100]
                DelayMS 1000
            Loop
        EndIf
        '
        ' Err, I, D
        '
        dLast_Err = dErr
        dErr = dTask - dTemp << 4
        If 32 < dPWR Then
            If dPWR < 65535 Then
                dInteg = dInteg + dErr
            EndIf
        EndIf
        dI = dInteg / fTi
        dDiff = dErr - dLast_Err
        DelayUS 10
        dD = dDiff * fTd

        If bMode = 2 Then
            dI = 0
            dD = 0                   ' P
        ElseIf bMode = 3 Then
            dI = 0                   ' PD
        ElseIf bMode = 4 Then
            dD = 0                   ' PI
        ElseIf bMode = 5 Then
            fKp = 255
            dI = 0
            dD = 0
        EndIf
        dPWR = dErr + dI + dD
        dPWR = fKp * dPWR
        If dPWR > 65535 Then
            dPWR = 65535
        ElseIf dPWR < 32 Then
            dPWR = 32
        ElseIf  tRun = 0 Then
            dPWR = 0
            dInteg = 0
        EndIf
        wCCP1_SFR = dPWR
        If wTMR1_SFR >= wCCP1_SFR Then PinClear TRIAC_Pin

        wLCD = dPWR * 100 / 65535
        INTCONbits_INTE = 0
        Print At 1, 14, Dec3 (dTemp + 4) >> 3,
              At 2, 5, Dec3 wLCD, $25
        INTCONbits_INTE = 1

        If tEFlag = 1 Then
            EWrite EE_Task, [dTask]
            tEFlag = 0
        EndIf
        DelayMS wT_Step - 4
    Loop

'-------------------------------------------------------------------------------
' Service Mode
'
Proc Service()
    If Service_Button = 1 Then                 '  Service
        Cls
        Print At 1, 2, "/Service Menu/"
        bChoice = 0
        tMenuFlag = 1

        Repeat
            If Service_Button = 1 Then   ' Service
                Inc bChoice
                Select bChoice
                    Case 1
                        Print At 2, 3, "Kp = ", Dec1 fKp / 10, " ", 8, "C", 9
                    Case 2
                        Print At 2, 3, "Td = ", Dec1 fTd / 10, " Sec  "
                    Case 3
                        Print At 2, 3, "Ti = ", Dec1 fTi / 10, " Sec  "
                    Case 4
                        Print At 2, 2, "T_Step = ", Dec wT_Step, " mS "
                    Case 5
                        Print At 2, 1, "T_PWM =      Sec"
                        Select bT_PWM
                            Case 1
                                Print At 2, 9, "0.25"
                            Case 2
                                Print At 2, 9, "0.50"
                            Case 3
                                Print At 2, 9, "0.75"
                            Case 4
                                Print At 2, 9, "1.00"
                            Case 5
                                Print At 2, 9, "1.50"
                            Case 6
                                Print At 2, 9, "2.00"
                        EndSelect
                    Case 6
                        Print At 2, 9, " Mode     "
                        Select bMode
                            Case 1
                                Print At 2, 1, "     PID"
                            Case 2
                                Print At 2, 1, "     P  "
                            Case 3
                                Print At 2, 1, "     PD "
                            Case 4
                                Print At 2, 1, "     PI "
                            Case 5
                                Print At 2, 1, "   Relay"
                        EndSelect
                EndSelect
                Repeat
                Until Service_Button = 0
                DelayMS 50
            EndIf
        Until bChoice > 6

        EWrite EE_Kp, [fKp]
        EWrite EE_Td, [fTd]
        EWrite EE_Ti, [fTi]
        EWrite EE_T_Step, [wT_Step]
        EWrite EE_T_PWM, [bT_PWM]
        EWrite EE_Mode, [bMode]
        EWrite EE_PR2, [PR2]
        tMenuFlag = 0
        Cls
        Print At 1, 7, "SAVED !"
        DelayMS 1000
    EndIf
EndProc

'-------------------------------------------------------------------------------
' Setup the program and peripherals
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    T1CON = %00000010
    CCP1CON = %00001000

    PinLow CLK_Pin
    PinLow DOUT_Pin
    PinHigh CS_Pin
    PinLow TRIAC_Pin
    PinInput Enc_Pin1
    PinInput Enc_Pin2
    PinInput Service_Button
    PinInput Run_Button

    dTask = ERead EE_Task
    fKp = ERead EE_Kp
    fTd = ERead EE_Td
    fTi = ERead EE_Ti
    wT_Step = ERead EE_T_Step
    bT_PWM = ERead EE_T_PWM
    bMode = ERead EE_Mode
    PR2 = ERead EE_PR2

    Print $FE, $40, $06, $09, $09, $06, $00, $00, $00, $00,
                    $01, $03, $19, $01, $01, $00, $00, $00

    HPWM 2, 127, 40000

    INTCONbits_INTE = 1
    PIE1bits_TMR1IE = 1
    PIE1bits_CCP1IE = 1
    INTCONbits_PEIE = 1
    INTCONbits_GIE = 1
EndProc

'-------------------------------------------------------------------------------
' Interrupt Handler
' Input     : None
' Output    : None
' Notes     : None
'
ISR_Handler:
    Context Save
    If PIR1bits_CCP1IF = 1 Then
        PinClear TRIAC_Pin
        PIR1bits_CCP1IF = 0
    EndIf
    If PIR1bits_TMR1IF = 1 Then
        PinSet TRIAC_Pin
        PIR1bits_TMR1IF = 0
    EndIf
    '
    ' Run
    '
    If Run_Button = 1 Then
        If tMenuFlag = 0 Then
            tRun = ~tRun
            T1CONbits_TMR1ON = tRun
            If  tRun = 0 Then
                PinClear TRIAC_Pin
                Print At 2, 12, "Stop"
            Else
                Print At 2, 12, "Run "
            EndIf
            Repeat : Until Run_Button = 0
            DelayMs 50
            INTCONbits_INTF = 0
        EndIf
    EndIf

    If INTCONbits_INTF = 1 Then
        If tMenuFlag = 0 Then
            If  Enc_Pin1 = 1 Then
                dTask = dTask + 8
            Else
                dTask = dTask - 8
            EndIf
            Print At 1, 5, Dec3 dTask >> 3
            tEFlag = 1
        EndIf
    EndIf

    If INTCONbits_INTF = 1 And tMenuFlag = 1 Then
        Select bChoice
            Case 1
                If Enc_Pin1 = 1 Then
                    Inc fKp
                Else
                    Dec fKp
                    If fKp < 0 Then fKp = 0
                EndIf
                Print At 2, 8, Dec1 fKp / 10
            Case 2
                If Enc_Pin1 = 1 Then
                    Inc fTd
                Else
                    Dec fTd
                    If fTd < 0 Then fTd = 0
                EndIf
                Print At 2, 8, Dec1 fTd / 10
            Case 3
                If Enc_Pin1 = 1 Then
                    Inc fTi
                Else
                    Dec fTi
                    If fTi < 0 Then fTi = 0
                EndIf
                Print At 2, 8, Dec1 fTi / 10
            '
            ' PID
            '
            Case 4
                If Enc_Pin1 = 1 Then
                    wT_Step = wT_Step + 100
                Else
                    wT_Step = wT_Step - 100
                    If wT_Step < 100 Then wT_Step = 100
                EndIf
                Print At 2, 11, Dec wT_Step

            Case 5
                If Enc_Pin1 = 1 Then
                    Inc bT_PWM
                    Select bT_PWM
                        Case 1
                            PR2 = 19
                            Print At 2, 9, "0.25"
                        Case 2
                            PR2 = 38
                            Print At 2, 9, "0.50"
                        Case 3
                            PR2 = 57
                            Print At 2, 9, "0.75"
                        Case 4
                            PR2 = 76
                            Print At 2, 9, "1.00"
                        Case 5
                            PR2 = 114
                            Print At 2, 9, "1.50"
                        Case 6
                            PR2 = 152
                            Print At 2, 9, "2.00"
                        Case >6
                            bT_PWM = 1
                            PR2 = 19
                            Print At 2, 9, "0.25"
                    EndSelect
                EndIf

            Case 6
                If Enc_Pin1 = 1 Then
                    Inc bMode
                    Select bMode
                        Case 1
                            Print At 2, 4, "  PID"
                        Case 2
                            Print At 2, 4, "  P  "
                        Case 3
                            Print At 2, 4, "  PD "
                        Case 4
                            Print At 2, 4, "  PI "
                        Case 5
                            Print At 2, 4, "Relay"
                        Case >5
                            bMode = 1
                            Print At 2, 4, "  PID"
                    EndSelect
                EndIf
        EndSelect
    EndIf
    INTCONbits_INTF = 0
    Context Restore



Pepe

#9
Try Now

Pepe

Try again, the variables must be signed so that if the temperature is exceeded the error is negative

Murat Atakan

Friends, there is no error in the program.
program proton 3.5.2.7
It works when compiled in the version.
The problem is that the system gets errors in higher version protons.
I couldn't figure this out.

Maxi

Quote from: Pepe on Jul 16, 2024, 07:51 PMTry again, the variables must be signed so that if the temperature is exceeded the error is negative
hi pepe,
Another problem has started.
At the first start, the power starts at 8%, whereas it should start at 100% and decrease as it approaches the setpoint.
Is it necessary to change the P-I-D values after the new software?

top204

#13
Version 3.5.2.7 dates back to October 2011. That is 13 years ago!, and there have been quite a few changes to the compilers since then.

If you had looked at the "Whats New.htm" file, that lists changes made to the compilers and is installed with every compiler revision and update, you would see that the next version up. i.e. version 3.5.2.9, added Signed Dword variables. So the standard Dword variable was unsigned and not default signed as it used to be, and the SDword is the 'new' signed 32-bit variable.

So Pepe is correct, the Dword variables also need to be made into SDword types.

With the tests I made of the software I tweaked, the temperature rose nicely and the PID worked well with the default parameters. However, I have changed the code listing I posted earlier and changed the Dword variables to SDword types.

It's just such a shame the code listing does not have any meaningful comments to state what each section of code is doing, because it actually works quite nicely. However, without comments, it would be difficult to tweak it for more efficiency and smaller code with any certainty of not breaking it. I have a feeling, some of the Dword variables were used because, at the time of its writing, they were the only signed integer variables in the compiler, and some could be reduced in size because the compiler now has signed SByte, SWord and SDword variables, and has had since 2012.

That's why all code I write has tidy comments, so you can see exactly what is happening in the code, and sometimes why it is happening. This then makes it possible to make changes to code years after it is initially created.

Murat Atakan

To all the friends who contributed.
Thanks a lot.