PIC16F1847 ADC and the Analog 2D Dashboard Component

An area to discuss 8-bit PIC specific problems and examples

Moderator: Benj

Post Reply
User avatar
the_hun
Posts: 9
Joined: Fri Dec 23, 2016 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

PIC16F1847 ADC and the Analog 2D Dashboard Component

Post by the_hun »

Greetings,

Today I spent most of my day chasing an anomaly in my project that involved 3 analog inputs on a PIC 16F1847... and to which I had found a workaround, but not sure if it is something I would use when I release my code for production use.

The details:
  • - The analog signals come in through channels AN0, AN1 and AN4.
  • - The code reads these voltages through component macros (via the built-in GetInt functions) and use their readings to trip safety features in the software (if conditions are right).
  • - To get the accuracy I needed I opted to use a 4.096V external reference IC on the VRef+ (AN3) pin of the PIC.
  • - During code development I used three, 2D dash panel analog inputs (pots) with the following identical configurations: VRef voltage: 401, VRef option: Vref+, Conversion Speed: FRC, Aquisition cycles: 50, Bit Depth: 10
  • - Tested the code using Flowcode's built-in simulation and was happy to see that all seemed to be OK.
  • - Next, I downloaded the code to my prototype board and tested the main software features again and that is when I saw a large (20%+) discrepancy between the calculated and actual safety trip points.
First, I thought I had a bad piece of hardware, but then I remembered the words of one of my former coworkers (RIP) who use to say that "if it ain't smoking.. its software" whenever I asked him to check the wiring of a newly-built test rack system.

So next, I did some calculations on the actual trip points and the voltages they supposed to trip at in real life and found that they correlate to the PIC's supply voltage (VDD), and not the external 4.096V reference. This prompted me to check the C code generated by Flowcode and tried to make some sense out of it all as I really did not know how it all worked behind the scenes.
Did not see anything bad so I have done some more digging, I found a file named "16F1847.fcdx" in the Flowcode package that had the following section in it, relating to the ADC of the 16F1847:
...
<adc type='23' bits='10' >
<speed >
<option name='Fosc / 2' value='0' />
<option name='Fosc / 8' value='1' />
<option name='Fosc / 32' value='2' />
<option name='FRC' value='3' />
<option name='Fosc / 4' value='4' />
<option name='Fosc / 16' value='5' />
<option name='Fosc / 64' value='6' />
</speed>
<vref>
<option name='VDD' value='0' />
<option name='Vref+' value='2' />
<option name='FVR' value='3' />
</vref>
</adc>
...
Then, I had located the function call within my project's auto generated C code and saw that it looked strange as it was calling out a non-existing positive voltage reference option of "1", while according to the "16F1847.fcdx" file it should be calling a "2". So I had come to a conclusion that for some reason when I select "Vref+" as an option in the 2D dash panel analog input component, it is really selecting something else.

To figure it out, I reconfigured all three of my analog inputs with different settings and compiled a new C file again in which then I looked to see what pull-down menu options in the analog input component create what option number in the C code. Here are the results:
  • AN0 --> 2D Dash Panel Settings --> VRef option: Vref+
    Related C code function call: FC_CAL_ADC_Enable(0, 3, 1, 40);
  • AN1 --> 2D Dash Panel Settings --> VRef option: VDD
    Related C code function call: FC_CAL_ADC_Enable(1, 3, 0, 60);
  • AN4 --> 2D Dash Panel Settings --> VRef option: FVR
    Related C code function call: FC_CAL_ADC_Enable(4, 3, 2, 50);
*NOTE: the acquisition cycle times of 40, 50 and 60 are not final. I only set them to different values in order to easier differentiate between the function calls.

The numbers we are interested in are the third ones in the parenthesis, which define the VRef+ option. From this and the code snippet from the file "16F1847.fcdx" above we can see that the two don't match.
In the fcdx file we get: VDD = 0, Vref+ = 2, FVR = 3,
while in the function calls the numbers are: VDD = 0, Vref+ = 1, FVR = 2

To test the theory, I set all three, 2D dash panel analog inputs to: "VRef option: FVR" and ran the code again on my prototype unit. It worked! My PIC was reading the 4.096V external reference IC. So now I know what the issue is and got a workaround, but I still have a couple of concerns that I would like to get some help with.
  • 1. I am not exactly sure if I had stumbled onto a bug or if there is something else in my project that does not work properly. Please let me know as I would really like to correct this before my final code release.
  • 2. I have also noticed that the input component does not have a pull-down menu for the VRef- setting of the PIC's ADC - which can be tied either to GND (VSS) or to the VRef- (AN2) pin of the chip. Is this something that can be done elsewhere in the code?
To provide some additional details about my findings, I am including compiler output message to show the selected MCU:

Target folder: ########################
Source name: ###########################################_16F1847.fcfx
Title: #########################.
Description:
Device: PIC.16F.16F1847
Generated by: Flowcode v7.2.1.4
Date: Sunday, June 11, 2017 11:29:00
Users: 1
Registered to: #########
Licence key: #########
http://www.matrixtsl.com
Launching the compiler...
C:\Program Files (x86)\Flowcode 7\compilers\pic\bin\xc8.exe --chip=16F1847 “##################_16F1847.c" --MSGDISABLE=359,1273,1388
Microchip MPLAB XC8 C Compiler (Free Mode) V1.41
Build date: Jan 24 2017
Part Support Version: 1.41
Copyright (C) 2017 Microchip Technology Inc.
License type: Node Configuration

. .


Memory Summary:
Program space used 1284h ( 4740) of 2000h words ( 57.9%)
Data space used DAh ( 218) of 400h bytes ( 21.3%)
EEPROM space used 18h ( 24) of 100h bytes ( 9.4%)
Data stack space used 0h ( 0) of 31Eh bytes ( 0.0%)
Configuration bits used 2h ( 2) of 2h words (100.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)


You have compiled in FREE mode.
Using Omniscient Code Generation that is available in PRO mode,
you could have produced up to 60% smaller and 400% faster code.
See http://www.microchip.com/MPLABXCcompilers for more information.


Launching the linker/assembler...
C:\Program Files (x86)\Flowcode 7\tools\DoNothing\DoNothing.exe


FINISHED

*******************************************************************************
*******************************************************************************


The three dash panel component properties (settings) and the function calls from the project C code:

AN4 Analog Input

2D Dash Panel Settings:
- VRef voltage: 401
- VRef option: FVR
- Conversion Speed: FRC
- Aquisition cycles: 50
- Bit Depth: 10

C Code:
/*=----------------------------------------------------------------------=*\
Use :Blocking call to read the ADC at full bit depth
:
:Returns : MX_UINT16
\*=----------------------------------------------------------------------=*/
MX_UINT16 FCD_08f43_adc_base__GetInt()
{
//Local variable definitions
MX_UINT16 FCR_RETVAL;


FC_CAL_ADC_Enable(4, 3, 2, 50);

FCR_RETVAL = FC_CAL_ADC_Sample(1);

FC_CAL_ADC_Disable();

return (FCR_RETVAL);

}

*******************************************************************************
*******************************************************************************

AN 0 Input:

2D Dash Panel Settings:
- VRef voltage: 401
- VRef option: Vref+
- Conversion Speed: FRC
- &
- Bit Depth: 10

C Code:
/*=----------------------------------------------------------------------=*\
Use :Blocking call to read the ADC at full bit depth
:
:Returns : MX_UINT16
\*=----------------------------------------------------------------------=*/
MX_UINT16 FCD_08f42_adc_base__GetInt()
{
//Local variable definitions
MX_UINT16 FCR_RETVAL;


FC_CAL_ADC_Enable(0, 3, 1, 40);

FCR_RETVAL = FC_CAL_ADC_Sample(1);

FC_CAL_ADC_Disable();

return (FCR_RETVAL);

}

*******************************************************************************
*******************************************************************************

AN 1 Input:

2D Dash Panel Settings:
- VRef voltage: 401
- VRef option: VDD
- Conversion Speed: FRC
- Aquisition cycles: 60
- Bit Depth: 10

C Code:

/*=----------------------------------------------------------------------=*\
Use :Blocking call to read the ADC at full bit depth
:
:Returns : MX_UINT16
\*=----------------------------------------------------------------------=*/
MX_UINT16 FCD_08f41_adc_base__GetInt()
{
//Local variable definitions
MX_UINT16 FCR_RETVAL;


FC_CAL_ADC_Enable(1, 3, 0, 60);

FCR_RETVAL = FC_CAL_ADC_Sample(1);

FC_CAL_ADC_Disable();

return (FCR_RETVAL);

}

*******************************************************************************
*******************************************************************************


Thanks in advance and cheers...

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: PIC16F1847 ADC and the Analog 2D Dashboard Component

Post by Benj »

Hello,

Thanks for the in depth report of the issue you're facing.
if it ain't smoking.. its software
Love it, what a quote! :D

I think I have now found and fixed the problem.

Simply copy the attached file into your "Flowcode 7/components" folder, restart Flowcode and the correct value should now be being passed to the CAL C code.
cal_adc.fcpx
(4.11 KiB) Downloaded 252 times
Let me know how you get on.

User avatar
the_hun
Posts: 9
Joined: Fri Dec 23, 2016 7:44 am
Has thanked: 3 times
Been thanked: 3 times
Contact:

Re: PIC16F1847 ADC and the Analog 2D Dashboard Component

Post by the_hun »

Hello, Ben,

Thank you much for the quick reply and for posting the updated ".fcpx" file.

Ir worked! The code compiles correctly now with the analog inputs' reference set to the external VRef+ pin. All three channels are reading what they are supposed to be reading. So this project is now almost done.

Thank you again. Really appreciate the help,
Jonathan

P.S.: Yes, a great saying from a great guy. He could always cheer us up when things didn't go as planned with a new test equipment release. :) An ex ballistic missile nuclear submariner from the Cold War era. Sadly, he must have spent too many years among nuclear warheads in the weapons silo of the sub (as a weapons officer) and thus cancer took him away before he could retire.

Post Reply