News:

;) This forum is the property of Proton software developers

Main Menu

Re-assign values to vars within the program

Started by Ecoli-557, Feb 03, 2025, 08:40 PM

Previous topic - Next topic

Ecoli-557

OK,
I am getting this down each day but I am trying to understand all the ways Les is able to use variables
I have 3 variables I wish to use to use Les' example of voltage divider but for two voltages.
Vars are: cR1, cR2, and AnaCH
I have tried every declaration of a variable in the manual and I still get errors for duplications.....
Code below:
'*******************************************************************************
ReadVoltages:
     dim cR1 as word shared 'Resistance var of R1 (in Ohms)
     dim cR2 as word shared 'Resistance var of R2 (in Ohms)
     'For the 5v input
     cR1 = 3000
     cR2 = 2000
     AnaCH = cANE6          'Selects 5v PORTE.6 - 5v
     Global_wVoltage = Voltage_Read()   'Read the voltage from the ADC
     ADC5vAcc = Global_wVoltage
     'For 24v input
     cR1 = 22000
     cR2 = 2000
     AnaCH = cANE5          'Selects 5v PORTE.5 - 24v
     Global_wVoltage = Voltage_Read()   'Read the voltage from the ADC
     ADC24vAcc = Global_wVoltage
Return
The theory is as the subroutine is called it first assigns the values required for 5v to get the correct value and then put it in a var to be sent out.
As it continues to go through the sub, the values are re-assigned to work with 24v which will get passed out as well.
It works just fine with just one voltage being digitized......
By the way, Thanks Les nifty way to do it and a great learning example!
Regards to All

Ecoli-557

A bit more information.
I get an assembly error and I do not know what it means:
'A.S 2951: Symbol not previously defined (PP1HH)'.  I get this for line 2980 as well:
Line 2951: MOVWF PP1HH,0
Line 2980: DECFSZ PP1HH,F

All relevant code here:
     dim cR1 as word 'Resistance var of R1 (in Ohms)
     dim cR2 as word 'Resistance var of R2 (in Ohms)

'*******************************************************************************
ReadVoltages:
Global_wVoltage = 0     'Zero var
ADC5vAcc = 0            'Zero var
ADC24vAcc = 0           'Zero var
'     dim cR1 as word 'Resistance var of R1 (in Ohms)
'     dim cR2 as word 'Resistance var of R2 (in Ohms)
     'For the 5v inputSymbol cR1           = 3000Symbol cR2           = 2000
     cR1 = 3000
     cR2 = 2000

'     dim cR1 as word = 3000
'     dim cR2 as word = 2000
     AnaCH = cANE6          'Selects 5v PORTE.6 - 5v
     Global_wVoltage = Voltage_Read()   'Read the voltage from the ADC
     ADC5vAcc = Global_wVoltage
'     $undef cR1 : $undef cR2   'Clears
     'For 24v input
'     cR1 = 22000
'     cR2 = 2000
'     dim cR1 as word = 22000
'     dim cR2 as word = 2000
'     AnaCH = cANE5          'Selects 5v PORTE.5 - 24v
'     Global_wVoltage = Voltage_Read()   'Read the voltage from the ADC
'     ADC24vAcc = Global_wVoltage
'     $undef cR1 : $undef cR2   'Clears
Return

'*******************************************************************************

'-------------------------------------------------------------------------------------------------------------
' Read the ADC and convert its raw value into a voltage value
' Output    : Returns the voltage as an integer, so a value of 102 for the voltage represents 10.2 volts
' Notes     : To display the voltage correctly, use a mechanism such as: HRsoutLn Dec VoltageResult / 10, ".", Dec1 VoltageResult // 10, "V"
Proc Voltage_Read(), Word
    Dim dVoltCalc  As Dword                                     ' Holds the 32-bit calculations to convert the ADC reading to a voltage value
    Dim wVoltage   As dVoltCalc.Word0                           ' Alias to hold the 16-bit calculations and the resulting voltage value
    Dim wADC_Value As dVoltCalc.Word1                           ' Alias to hold the raw ADC reading

    Symbol cVref         = 500000                               ' The +Vref voltage used by the ADC (multiplied by 100000)
    Symbol cADC_ResValue = 1024                                 ' The maximum value from the ADC's resolution
    Symbol cQuanta       = (cVref / cADC_ResValue)              ' The quantasisation value for the ADC's +Vref and the ADC's resolution value
'    Symbol cR1           = 3000                               ' Resistance of R1 (in Ohms)
'    Symbol cR2           = 2000                                ' Resistance of R2 (in Ohms)
    Symbol cRdivCalc     = ((cR2 * 100) / (cR1 + cR2))          ' A calculation for the resistor divider

    wADC_Value = ADC_Read10(AnaCH)                              ' Read the ADC from the selected channel
    dVoltCalc = wADC_Value * cQuanta                            ' Convert the 10-bit ADC value into a 32-bit voltage value
    wVoltage = dVoltCalc / cRdivCalc                            ' Take the resistor divider into account for the final voltage calculation
    wVoltage = wVoltage / 100                                   ' Make the final voltage value a smaller integer value
    Result = wVoltage                                           ' Return the smaller voltage value
EndProc

'------------------------------------------------------------------------------------------------
' Get a 10-bit reading from the ADC on a PIC18F67K40 device
' Input     : pChan holds the ADC channel to read
' Output    : Returns the 10-bit ADC value. Also held in SFRs ADRESL and ADRESH
' Notes     : Sets the ADFM bit to right justified 10-bit operation
Proc ADC_Read10(pChan As WREG), ADC10_wADRES
Global Dim ADC10_wADRES As ADRESL.Word                          ' Create a global 16-bit SFR from SFRs ADRESL and ADRESH
    ADPCH = pChan                                               ' Load the channel into the relevant SFR
    ADCON0bits_ADFM = 1                                         ' Set the ADFM bit for right justified
    ADCON0bits_ADON = 1                                         ' Enable the ADC
    DelayUS 50                                                  ' A delay before sampling
    ADCON0bits_GO_DONE = 1                                      ' \
    Repeat : Until ADCON0bits_GO_DONE = 0                       ' / Start a sample and wait for it to finish
EndProc


The Subroutine ReadVoltages calls the Procedures.
As far as I understand this, this should work but it does not and I need a way to understand why so I can un-comment the code in the ReadVoltages subroutine in order to read both 5v and 24v.
I am sure I can use a SelectCase or an IF-Then to select 5v or 24v but there should be a more elegant way to do this?

Ecoli-557

I am moving on.  I used a copy of the original Procedure for 24v.
Code below for any information - not too much.
'-------------------------------------------------------------------------------------------------------------
' Read the ADC and convert its raw value into a voltage value
' Output    : Returns the voltage as an integer, so a value of 102 for the voltage represents 10.2 volts
' Notes     : To display the voltage correctly, use a mechanism such as: HRsoutLn Dec VoltageResult / 10, ".", Dec1 VoltageResult // 10, "V"
Proc Five_Read(), Word
    Dim dVoltCalc  As Dword                                     ' Holds the 32-bit calculations to convert the ADC reading to a voltage value
    Dim wVoltage   As dVoltCalc.Word0                           ' Alias to hold the 16-bit calculations and the resulting voltage value
    Dim wADC_Value As dVoltCalc.Word1                           ' Alias to hold the raw ADC reading

    Symbol cVref         = 500000                               ' The +Vref voltage used by the ADC (multiplied by 100000)
    Symbol cADC_ResValue = 1024                                 ' The maximum value from the ADC's resolution
    Symbol cQuanta       = (cVref / cADC_ResValue)              ' The quantasisation value for the ADC's +Vref and the ADC's resolution value
    Symbol cR5v          = 3000                               ' Resistance of R1 (in Ohms)
    Symbol cR2           = 2000                                ' Resistance of R2 (in Ohms)
    Symbol cRdivCalc     = ((cR2 * 100) / (cR5v + cR2))          ' A calculation for the resistor divider

    wADC_Value = ADC_Read10(cANE6)                              ' Read the ADC from the selected channel
    dVoltCalc = wADC_Value * cQuanta                            ' Convert the 10-bit ADC value into a 32-bit voltage value
    wVoltage = dVoltCalc / cRdivCalc                            ' Take the resistor divider into account for the final voltage calculation
    wVoltage = wVoltage / 100                                   ' Make the final voltage value a smaller integer value
    Result = wVoltage                                           ' Return the smaller voltage value
EndProc

'-------------------------------------------------------------------------------------------------------------
' Read the ADC and convert its raw value into a voltage value
' Output    : Returns the voltage as an integer, so a value of 102 for the voltage represents 10.2 volts
' Notes     : To display the voltage correctly, use a mechanism such as: HRsoutLn Dec VoltageResult / 10, ".", Dec1 VoltageResult // 10, "V"
Proc TwentyFour_Read(), Word
    Dim dVoltCalc  As Dword                                     ' Holds the 32-bit calculations to convert the ADC reading to a voltage value
    Dim wVoltage   As dVoltCalc.Word0                           ' Alias to hold the 16-bit calculations and the resulting voltage value
    Dim wADC_Value As dVoltCalc.Word1                           ' Alias to hold the raw ADC reading

    Symbol cVref         = 500000                               ' The +Vref voltage used by the ADC (multiplied by 100000)
    Symbol cADC_ResValue = 1024                                 ' The maximum value from the ADC's resolution
    Symbol cQuanta       = (cVref / cADC_ResValue)              ' The quantasisation value for the ADC's +Vref and the ADC's resolution value
    Symbol cR24v         = 22000                               ' Resistance of R1 (in Ohms)
    Symbol cR2           = 2000                                ' Resistance of R2 (in Ohms)
    Symbol cRdivCalc     = ((cR2 * 100) / (cR24v + cR2))          ' A calculation for the resistor divider

    wADC_Value = ADC_Read10(cANE5)                              ' Read the ADC from the selected channel
    dVoltCalc = wADC_Value * cQuanta                            ' Convert the 10-bit ADC value into a 32-bit voltage value
    wVoltage = dVoltCalc / cRdivCalc                            ' Take the resistor divider into account for the final voltage calculation
    wVoltage = wVoltage / 100                                   ' Make the final voltage value a smaller integer value
    Result = wVoltage                                           ' Return the smaller voltage value
EndProc


'------------------------------------------------------------------------------------------------
' Get a 10-bit reading from the ADC on a PIC18F67K40 device
' Input     : pChan holds the ADC channel to read
' Output    : Returns the 10-bit ADC value. Also held in SFRs ADRESL and ADRESH
' Notes     : Sets the ADFM bit to right justified 10-bit operation
Proc ADC_Read10(pChan As WREG), ADC10_wADRES
Global Dim ADC10_wADRES As ADRESL.Word                          ' Create a global 16-bit SFR from SFRs ADRESL and ADRESH
    ADPCH = pChan                                               ' Load the channel into the relevant SFR
    ADCON0bits_ADFM = 1                                         ' Set the ADFM bit for right justified
    ADCON0bits_ADON = 1                                         ' Enable the ADC
    DelayUS 50                                                  ' A delay before sampling
    ADCON0bits_GO_DONE = 1                                      ' \
    Repeat : Until ADCON0bits_GO_DONE = 0                       ' / Start a sample and wait for it to finish
EndProc


I may loop around this at some other point but am leaving it for now.
I thought procedures with their own self sustained environment would be the way to go.... clearly, I have much more figuring to do.
Regards to All.

top204

I need to know the device you are using, and a code snippet that shows the assembler error. It appears to be when calling a library subroutine of some sort, and it is not creating all the internal system variables for it.

Each of the device families are very different to each other, so the compiler has to jump to differnt functions withi itself, or differnt sections with a function for the family type. i.e Standard 12-bit core, standard 14-bit core, enhanced 14-bit core, and 18F types.

Assembler code for one will not always work on another, and RAM allocation for the devices families is very, very different, as are the library subroutines and thier requirements.

Ecoli-557

Les,
The chip I am using is PIC18F67K40,
I will have to re-write the section and run it again, may take a few days.
Thanks for wanting to help.
Regards.