Range detection not working properly with PSoC 4 ADC SAR SEQ

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Doorknob
Level 4
Level 4
First solution authored 50 replies posted 25 replies posted

I am currently using a PSoC 4 and a ADC SAR SEQ ADC to measure current of two Infineon IFX007TAUMA1 half bridge parts.  I have set my range high limit to what i believe  is 750mV but the SAR ADC always trips early.  I believe I have done all my setup and math correctly.  I was hoping some could look over my project and  to see what i have done or calculated wrong.

Problem:

Note in this project I am driving a large motor in two directions with two 55 Amp  Infineon  IFX007TAUMA1 half bridge parts.   I run my system from 10 to 36 Volts DC.  Every thing works properly as far as code and interrupts, but I can not seem to be able to get the range detection setting of 750mV to activate or trip at this voltage.  It always trips at a much lover voltage around 450mV to 500mV.

In my code I deactivate the range detection interrupt for 150mS to accommodate the high spike in current when the motor first turns on/reverses direction.  I then activate the range detection in the ADC for detecting motor over current threshold set by.

This all seems to work but not at 750mV as expected

Below I have attached output of the current wave form from the Infineon half bridge current sense pin that is feed into one of the inputs of the ADC. Note after the initial current spike the current settles to about 500mV.

I will attach below my EXCEL calculations for setting the current range settings in Hex.

I am hoping someone can help with what i am doing wrong

Thanks

Scott

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

I ran search for AN/KBA for this topic, but I could not find a good one.

The only think I came up with was the data sheet of the component,

which I'm afraid that is the same one with what we can access from the component.

PSoC 4 Sequencing Successive Approximatin ADC (ADC_SAR_Seq)

https://www.cypress.com/documentation/component-datasheets/psoc-4-sequencing-successive-approximatio...

Meantime, since you are using 4200M (CY8C4247AZI-M485), having TRM (Technical Reference Maual) and Datasheet is a good idea,

in case if you have not done so.

PSoC 4100M / PSoC 4200M Family: PSoC® 4 Architecture Technical Reference Manual (TRM)

https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100m-psoc-4200m-family-psoc-...

PSoC 4100M/4200M Family: PSoC® 4 Registers Technical Reference Manual (TRM)

https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100m4200m-family-psoc-4-regi...

PSoC® 4: PSoC 4200M Family Datasheet Programmable System-on-Chip (PSoC®)

https://www.cypress.com/documentation/datasheets/psoc-4-psoc-4200m-family-datasheet-programmable-sys...

Having written above, I tried a little wordy explanation of the "Single ended result format" table attached in the previous response.

Assuming the resolution is 12 bit signed (2's complement format)

ADC maps +Vref to 0x7FF (2047) and -Vref to 0x800 (-2048) as below.    

008-range-2-comp.JPG

As you can see, in the "bin" column, all the positive values has '0' in the left most position, which is MSB.

On the other hand all the negative values has '1' in MSB.

So if you see only the positive part, you don't need the MSB, so you can consider it as 11bit,

but to utilize full 11bit for the value, it must be "unsigned" otherwise the values with '1' in their MSB will be treated as negative values in "signed".

Please refer to the Wikipedia for the better explanation.

https://en.wikipedia.org/wiki/Two%27s_complement

Best Regards,

12-Jul-2020

Motoo Tanaka

P.S. It would be greatly appreciated if you could mark my response(s) as "Helpful" or "Correct Answer" if it is so.

View solution in original post

14 Replies
Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Scott,

I am having difficulty in opening your project. Could you please follow the procedure below to attach the project ? In PSoC Creator ,  go to File -> Create Workspace Bundle -> Select minimal. Please attach the generated file.

Best Regards,
Vasanth

0 Likes
lock attach
Attachments are accessible only for community members.

Here is bundle created with minimum.

Scott

0 Likes
lock attach
Attachments are accessible only for community members.

Vasanth attached is bundle with minimal selected .... Scott

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

The size of your zip files shows 792 bytes,

which is too small for a project archive.

I'm afraid that something is going wrong.

Could you try the steps shown in the following discussion?

Re: How to attach a project archive file to a question?

Best Regards,

5-Jul-2020

Motoo Tanaka

0 Likes
lock attach
Attachments are accessible only for community members.

Motoo ... thank you for trying to help me with my issue.  In the past i would use the bundle from the main file drop down not the drop down from the project it self.  I will attach the project as your posted.

Thanks again for your help!

Scott

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

Finally, I could download and expand your project.

I tried the following test with CY8CKIT-044.

schematic

Note: I copied your ADC and added a UART to see the result.

002-schematic.JPG

pins

Note: I connected a couple of POTs to IS1 and IS2

003-pins.JPG

main.c

Note: I used your macro definitions, global variables and ADC ISR.

================

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char str[STR_LEN+1] ;

void print(char *str)

{

    UART_UartPutString(str) ;

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(void)

{

    cls() ;

    print("ADC Range Test") ;

    snprintf(str, STR_LEN, " (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;   

}

/* Macro definitions */

#define LOW                 (0u)

#define HIGH                (1u)

#define ADC_Ch0_IS1         (0u)

#define ADC_Ch1_IS2         (1u)

#define ADC_Ch2_IS3         (2u)

#define ADC_Ch3_IS4         (3u)

#define ADC_Ch4_Pot1        (4u)

#define ADC_Ch5_Pot2        (5u)

#define ADC_Ch6_Volt        (6u)

#define ADC_Ch7_T_Pos       (7u)

#define ADC_Ch8_T_Neg       (8u)

#define CONVERT_TO_ASCII    (0x30u)

/* Global Variables */

volatile uint32 windowFlag = 0u;

volatile uint8  dataReady = 0u;

volatile uint8  TestFlag = 0u;

volatile uint16 Blend_CMP = 0u;

volatile uint16 IS1_Count =0u;

volatile uint16 IS2_Count =0u;

volatile uint16 IS1_mVolts =0u;

volatile uint16 IS2_mVolts =0u;

volatile uint8  Mode_Max = 2u;

volatile uint16 adcCount[9u];

char   tmpStr[25];

CY_ISR_PROTO(ADC_ISR_Handler) ;

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    UART_Start() ;

    ADC_Start() ;

    ADC_IRQ_StartEx(ADC_ISR_Handler) ;   

}

void measure(void)

{

    ADC_StartConvert() ;

//    ADC_IsEndConversion(ADC_WAIT_FOR_RESULT) ;

    while(dataReady == 0u)

    {

         ; /* Wait for ADC conversion */

    }

    adcCount[ADC_Ch0_IS1] = ADC_GetResult16(ADC_Ch0_IS1) ;

    adcCount[ADC_Ch1_IS2] = ADC_GetResult16(ADC_Ch1_IS2) ;

   

    IS1_mVolts = ADC_CountsTo_mVolts(ADC_Ch0_IS1,adcCount[ADC_Ch0_IS1]);

    IS2_mVolts = ADC_CountsTo_mVolts(ADC_Ch1_IS2,adcCount[ADC_Ch1_IS2]);

    snprintf(str, STR_LEN, "IS1=%4d mV [%04d] IS2=%4d mV [%04d] ",

        IS1_mVolts, adcCount[ADC_Ch0_IS1],

        IS2_mVolts, adcCount[ADC_Ch1_IS2]

    ) ;

    print(str) ;   

}

int main(void)

{

    init_hardware() ;

   

    splash() ;

    for(;;)

    {

        measure() ;

       

        /* Check for ADC widnow current limit interrupt activation */

        if (windowFlag) {

            print("windowFlag") ;

            ADC_StopConvert() ;

            dataReady = 0u ;

            windowFlag = 0u ;

        }

        print("\n") ;

        CyDelay(500) ;

    }

}

/**************************************************************************

* Function Name: ADC_ISR_Handler                                          *

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

*                                                                         *

* Summary:                                                                *

* Interrupt Service Routine: Check the ADC status and sets window         *

* and data ready flags.                                                   *

*                                                                         *

***************************************************************************/

CY_ISR(ADC_ISR_Handler)

{

   uint32 intr_status;

   

    /* Read interrupt status registers */

    intr_status = ADC_SAR_INTR_MASKED_REG;

    /* Check for End of Scan interrupt */

    if ((intr_status & ADC_EOS_MASK) != 0u)

    {

        /* Read range interrupt status and raise the flag */

        windowFlag = ADC_SAR_RANGE_INTR_MASKED_REG;

        /* Clear range detect status */

        ADC_SAR_RANGE_INTR_REG = windowFlag;

        dataReady = 1u;

    }

    /* Clear handled interrupt */

    ADC_SAR_INTR_REG = intr_status;

}

================

Tera Term Log

Note: I set 1 pot to (around) 750mV the count was (around) 460,

and I set the other pot to count (around) 153 (= hex 88)  the voltage was 243mV.

001-TeraTerm-log.JPG

So my conclusion is that if you want check range around 750 mV you need to set the value around 460~.

Best Regards,

7-Jul-2020

Motoo Tanaka

0 Likes
lock attach
Attachments are accessible only for community members.

Motoo,

Thank you so much for checking my system.  You have basically showed that I either have a problem in my math or there is some other principle I do not understand for calculating count/Hex values for a ADC range settings.

Since I have posted my question and waiting have have basically done the same thing and posted the ADC values to the UART which were converted to mVolts.  This seems to work perfectly, and if i use these results in code to make decisions it works just great.  Yet I want the PSoC to do it out side of my code so I can have my service to the range faults quick as possible and also my make my code simple.  So the question is whats the proper math for converting volts to count/Hex properly for these range settings?

I thought I understood this process properly in my attached  spread sheet i used to calculate the count values and the hex values for these range settings.  From my math a count value of 460 translates to 2.25 Volts not 750mV.    For me this does not set right I should be able to have my math correlate to whats on chip for these range settings.

Do you see anything wrong  in math in the attached spread sheet for calculating count/hex values for these range settings.  Is there any other information available on calculating these range settings that you are aware of?

Thanks

Scott

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

PSoC Creator's components have their datasheet attached.

We can access the datasheet either from the Component Catalog or from the Configuration Dialog of the component.

From Component Catalog

There is "Open datasheet" in the left - upper corner of the component sample display.

006-component-catalog.JPG

From the Configuration dialog

003-Datasheet.JPG

And in the ADC SAR Seq's Datasheet I found the following table.

Since we are using Single Ended, Singed with input from 0 to Vref (VDDA),

0 V = 0x0000

3.3 V = 0x07FF

005-SingleEnded_Result-format.JPG

Then I ran my program again

0 mV -> 0x000 (0)

3197 mV -> 0x7C0 (1984)

004-TeraTerm-log.JPG

I think that 3300 mV would be 0x7FF but my hardware could not reach there.

From the measured value if count == 460, the voltage would be 741 mV

460 * 1984 / 3197 = 741.24 (mV)

From the table above if count == 460,

460 * 2047 (0x7FF) / 3300 = 741.57 (mV)

So the value in the table and the measured value seem to agree.

I wonder if I could answer to your question.

Best Regards,

10-Jul-2020

Motoo Tanaka

Motoo,

Your efforts are so much appreciated thank you!  My question still is not answered though.  To me the math with units needs to make since not just results back feed, although in the end are reality.

From what I have determined my math is correct but my understanding of the data sheet is not making since to me... Can you explain the following observations/decisions I have made?

1st .. This is my ADC Setup from the component.

ADC_Settings.png

In my system my VDDA is 5 Volts, which I set in the my System settings in my project.  The 5V Vref value  is my maximum value for the Single ended positive input for each of the ADC inputs.  The Single ended negative input is Vss.  As you can see above my input range is 0.0 to Vref (5V).

2nd .. The next step is were I went wrong and am confused why.  Below is the section of the data sheet were it talks about Single ended result format. Notice below for single ended result -Input connected to Vss and +Input connected to Vref the result register is 12 Bit.  If is use 12 bit in my math the ADC range settings do work properly with my math and the actual board results.

     Yet if you read further in the data sheet and this is were I change my math from  to 11 bit because (See below were I highlighted in red) is says .... For single-ended conversions with the Single ended negative input parameter set to Vss, the conversion is effectively 11-bit, because voltages below Vss are illegal on any PSoC 4 pin.  So reading this i changed my math to 11-bit and if i do this I get bad results.

Can this be explained to me why the discrepancy between 11-Bit and 12-Bit?  What am i not understanding here?

Single Ended Result Format.png

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

I'm sorry for my poor explanation(s), which failed to make sense.

First of all the next page of the table in the datasheet there is the following table.

007-Data_Fromat_Justification.JPG

Although you are saying that you made it to 11bit, for a 12bit signed integer, the MSB "MUST" be '0' or you get a negative value.

Which means that the bit11 (and bit[15:12] also) must be '0' to make the value positive.

Another thing bothered me was that you were defining adcCount as

volatile uint16 adcCount[9u] ;

If ADC is set to "Signed" it must be

volatile int16 adcCount[9u] ;

BTW, here is another catch.

Although datasheet states that the minimum value is vss, as vss has some "floating" value, which means vss is not Zero but has some positive value.

Applying GND voltage results a "negative" reading from the ADC, so we need to check if the result from ADC is positive,

and if it's negative, in my case, usually I replace the result with '0' so that the following calculation will make sense.

This is my idea off my head, and I have not tried, but in case you "NEED" to get 11bit value out of the 12bit signed value,

which is guaranteed to be positive, we my be able to do

int16_t adc_raw_count ;

uint16_t adc_11bit_value ;

adc_raw_count = ADC_GetResult16(theChannel) ;

adc_11bit_value = (uint16_t) (adc_raw_count & 0x07FF) ;

Best Regards,

11-Jul-2020

Motoo Tanaka

Motoo,

First off Motto your explanations are great and make since!  Your are just trying to help a guy who is a very slow learner and new to this type of application and coding.  I wan to thank you again for helping me understand, which really mean a lot!  Thank you

Ok I believe i am starting to get the full picture now ... dealing with a signed values is still not quite clear to me on how this would be done. 

Questions: So as long as my values I am reading are positive I can use the whole 12 bits.  If i was dealing with signed values would half the values represent negative numbers?

Question: is there an application note or other information available were i learn more about the measuring negative numbers and dealing with them?

Motoo, I will correct my mistake on my singed verses unsigned variables.  As you can see i did not fully understand what I was doing.

Thank you again for helping me to fully understand.  My original question is fully answered.  I now need to put my head around dealing with negative values.

Scott

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Scott-san,

I ran search for AN/KBA for this topic, but I could not find a good one.

The only think I came up with was the data sheet of the component,

which I'm afraid that is the same one with what we can access from the component.

PSoC 4 Sequencing Successive Approximatin ADC (ADC_SAR_Seq)

https://www.cypress.com/documentation/component-datasheets/psoc-4-sequencing-successive-approximatio...

Meantime, since you are using 4200M (CY8C4247AZI-M485), having TRM (Technical Reference Maual) and Datasheet is a good idea,

in case if you have not done so.

PSoC 4100M / PSoC 4200M Family: PSoC® 4 Architecture Technical Reference Manual (TRM)

https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100m-psoc-4200m-family-psoc-...

PSoC 4100M/4200M Family: PSoC® 4 Registers Technical Reference Manual (TRM)

https://www.cypress.com/documentation/technical-reference-manuals/psoc-4100m4200m-family-psoc-4-regi...

PSoC® 4: PSoC 4200M Family Datasheet Programmable System-on-Chip (PSoC®)

https://www.cypress.com/documentation/datasheets/psoc-4-psoc-4200m-family-datasheet-programmable-sys...

Having written above, I tried a little wordy explanation of the "Single ended result format" table attached in the previous response.

Assuming the resolution is 12 bit signed (2's complement format)

ADC maps +Vref to 0x7FF (2047) and -Vref to 0x800 (-2048) as below.    

008-range-2-comp.JPG

As you can see, in the "bin" column, all the positive values has '0' in the left most position, which is MSB.

On the other hand all the negative values has '1' in MSB.

So if you see only the positive part, you don't need the MSB, so you can consider it as 11bit,

but to utilize full 11bit for the value, it must be "unsigned" otherwise the values with '1' in their MSB will be treated as negative values in "signed".

Please refer to the Wikipedia for the better explanation.

https://en.wikipedia.org/wiki/Two%27s_complement

Best Regards,

12-Jul-2020

Motoo Tanaka

P.S. It would be greatly appreciated if you could mark my response(s) as "Helpful" or "Correct Answer" if it is so.

Vasanth
Moderator
Moderator
Moderator
250 sign-ins 500 solutions authored First question asked

Hi Scott,

Additional to what Moto san has said and to answer your question regarding ADC resolution, the SAR ADC in PSoC is differential in architecture. In single ended mode when negative input is connected to VSS, this means that half the range of the ADC will not able to used. This is because PSoC cannot work any voltage below VSS. This is the reason where the 11 bit resolution originates from.

Best Regards,
Vasanth

Vasanth,

thank you for your reply ... now i know why there is the difference between the 12 bit and the 11 bit values.  I honestly was confused as to when to use the 11 bit value.

Its really nice to have the help from people like Motoo and people like you.

This really helped Thank you!

Best Regards

Scott