PSoC5LP as SPIM and MCP3201 as SPIS

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.
NaAh_4673366
Level 3
Level 3
5 likes given First like received First like given

Hi Everyone,

I am facing a problem with SPI communication. I am trying to read data from an external ADC (MCP3201), transform it to temperature value and show it in PUTTY terminal using UART. But I always get garbage value. I am using the ADC as SPI slave and PSOC5LP as SPI Master. I don't understand why I am not getting correct values. Can anyone help? Thanks.

0 Likes
1 Solution

Dear Motoo Tanaka,

Thanks for all of your helps. I just found out the problem. It was needed to connect a 10uF capacitor to the Vout pin of

the MCP1541 voltage reference to get stable values. It was my mistake that I overlooked the datasheet information:

VR.PNG

I apologize that I wasted your tiime. Thanks again for all of your efforts.

temp.PNG

Best Regards,

Nasir Ahmed

View solution in original post

17 Replies
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

Hi,

Please read Page 21 of the MCP3201 Datasheet

001-datasheet.JPG

So there were 3 points, I'd like to modify your code

(1) Make SPI data width to 16 (to make it multiple of 😎

(2) Wait till all TX data is sent

(3) Use only  12 bits of the received data, after shifting it 1 bit right

(1) SPI data width to 16

002-SPIM.JPG

(2) Wait till all tx data is sent

I added "while" line after SPIM_WriteTxData() line

=========

                SPIM_WriteTxData(0xFFFF);

               

                while(SPIM_GetTxBufferSize()) { } /* wait till tx buffer is sent */

=========

(3) Mask 2 MSB bit of the received data, after shifting it 1 bit right

To do this, I introduced a working variable spi_raw_data in the beginning of main()

=========

int main()

{

    uint16_t spi_raw_data  ;   

    /* Enable global interrupts */

    CyGlobalIntEnable;

=========

Then I modified the if (SPIM_STS_RX_FIFO_NOT_EMPTY) block as below.

Please Note that I'm not sure about the conversion from spi_raw_data to SPItemp.

========

                if(SPIM_STS_RX_FIFO_NOT_EMPTY){

                    spi_raw_data = SPIM_ReadRxData() ;

                    spi_raw_data = (spi_raw_data >> 1) & 0x0FFF ; /* see page 21 of the MCP3201 datasheet */

                    SPItemp = (spi_raw_data * 4.096) / 4095 * 100 ;

                    // SPItemp = (SPIM_ReadRxData()*4.096)/4095*100;

                    SPIM_ClearRxBuffer();

                    SPIM_ClearTxBuffer();

                }

========

Since I don't have the sensor, I'm not sure if this works with your hardware.

In case it does not work, I'm sorry.

moto

Hi ,

thanks for your response. Hope you are doing well in this current situation.

It still does the same thing. Really don't understand why.

About the conversion from spi_raw_data to SPItemp: I used an analog temperature sensor LM35DZ as the input for the external ADC (MCP3201) and MCP1541 voltage reference for MCP3201 reference input.

So in the calculation part, I just calculated the temperature value using the SPIM_ReadRxData().

nasir ahmed

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

Dear Nasir-san,

> It still does the same thing. Really don't understand why.

Could you add screen copy or log of what you are getting?

Or for the debugging, can you add a couple of lines to see the value of spi_raw_data something like below

before your sprintf() line?

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

sprintf(TransmitBuffer, "spi_raw_data: 0x%04X ", spi_raw_data) ;

UART_1_PutString(TransmitBuffer) ;

/* Format ADC result for transmition */

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

And if you still see "random" value, please double check the connection between

PSoC 5LP and the Sensor.  Namely, SPICLK, SPISS, SPIMISO, and GND

> About the conversion from spi_raw_data to SPItemp

This is OK, as far as the spi_raw_data seems stable it won't be a problem.

I meant that I was just caring about the behavior of the SPI data.

Best Regards,

30-Apr-2020

Motoo Tanaka

lock attach
Attachments are accessible only for community members.

Dear Motoo Tanaka,

Now I see, I am getting too big numbers. Here is the picture:

SPI.jpg

Any idea, why?MoTa_728816

Best Regards,

Nasir Ahmed

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

Hi,

The number(s) returned from the sensor may be a signed value.

Could you try this?

==========

int16_t s_value ;

..

s_value = (int16_t) (spi_raw_data << 4) ;

sprintf(TransmitBuffer, "spi_raw_data: 0x04X = %d ", spi_raw_data, s_value) ;

UART_1_PutString(TransmitBuffer) ;

==========

moto

0 Likes

Hi MoTa_728816,

Now I am getting this:

SPI2.PNG

And a Warning says: "data argument not used by format string":

SPI3.PNG

nasir

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

Dear Nasir-san,

I just tested the values printed in your screen copy with Cygwin.

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

111111010101 : raw_value = 0x0FD5, = -688

111110101111 : raw_value = 0x0FAF, = -1296

111111111111 : raw_value = 0x0FFF, = -16

111101010111 : raw_value = 0x0F57, = -2704

111111111101 : raw_value = 0x0FFD, = -48

111111111110 : raw_value = 0x0FFE, = -32

111111111111 : raw_value = 0x0FFF, = -16

111111111101 : raw_value = 0x0FFD, = -48

111101010101 : raw_value = 0x0F55, = -2736

111111101010 : raw_value = 0x0FEA, = -352

011111111111 : raw_value = 0x07FF, = 32752

111111111010 : raw_value = 0x0FFA, = -96

110101111111 : raw_value = 0x0D7F, = -10256

111111111110 : raw_value = 0x0FFE, = -32

111101010111 : raw_value = 0x0F57, = -2704

111111111010 : raw_value = 0x0FFA, = -96

110101111111 : raw_value = 0x0D7F, = -10256

111111101010 : raw_value = 0x0FEA, = -352

110101010111 : raw_value = 0x0D57, = -10896

110101111111 : raw_value = 0x0D7F, = -10256

111111111111 : raw_value = 0x0FFF, = -16

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

As you have been saying from the beginning, the values seems to be quite random.

What I can imagine at this point is

(1) The Sensor is not working as it is expected

(2) The SPI connection is wrong

To check the behavior of the internal SPI component,

please try to connect the MISO signal to GND and if the value will stay to 0x0000,

as well as pull the signal to HIGH, may be using some resistor to VDD and if the value will be 0x0FFF.

Then can you make the input to the MCP3201 to be a stable value and see if the SPI reading will stay same or not.

I wonder what is the volatge of IN+/IN- and VREF connected to the MCP3201.

Best Regards,

30-Apr-2020

Motoo Tanaka

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

Dear Nasir-san,

I'm sorry

> sprintf(TransmitBuffer, "spi_raw_data: 0x04X = %d ", spi_raw_data, s_value) ;

should have been

< sprintf(TransmitBuffer, "spi_raw_data: 0x%04X = %d ", spi_raw_data, s_value) ;

An additional thoughts in the MCP3201 datasheet there is an equation in EQUATION 4-2:

010-Equation_4_2.JPG

If we assume that the "Digital Output Code" = spi_raw_data

     Vin = (Vref * spi_raw_data) / 4096 ;

But your equation was

     SPITemp = spi_raw_data * 4.096 / 4095 * 100 ;

Is the Vref is 4.096V ?

Then SPITemp will be

     100 x Vin = (spi_raw_data * 4.096 / 4095) * 100 ;

or were you expecting

     SPITemp = (spi_raw_data * 4.096 / (4095 * 100)) ?

Anyway I have a little doubt about the equation.

But even equation is wrong, it does not explain the random-ness of the reading value.

Could you measure the IN+, IN- and Vref ?

And again, please make sure that SPICLK, SPISS, SPIMISO, and GND are connected correctly?

Best Regards,

30-Apr-2020

Motoo Tanaka

0 Likes

Dear MoTa_728816,

yes the equation is : Vin = (Vref * spi_raw_data) / 4096 ;

And if I want to transform Vin to Temperature in celcius first I have to multiply it with 1000 so that I get the Voltage in mV and than

devide it by 10 ( 1°C is 10 mV).

so I am getting the final equation:

SPITemp = (spi_raw_data * 4.096 / (4095 * 100))

0 Likes

Dear MoTa_728816,

I checked the connection of SPICLK, SPISS, SPIMISO, and GND and they are correctly connected.

Best Regards,

nasir

0 Likes

Hi MoTa_728816,

As you said I connected MISO signal to GND and got 0x0FFF

Spi4.PNG

connection of IN+/IN- and VREF: I connencted IN+ to the OUTPUT pin of temperature Sensor LM35DZ(5 V) and IN- to the ground (0 V). VREF to the output pin of voltage reference MCP1541 ​(4.096 V)

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

Dear Nasir-san,

> As you said I connected MISO signal to GND and got 0x0FFF

That is very interesting.

SPI should get 0x0000 instead of 0x0FFF.

I wonder if you connected MISO to VDD or something is very wrong.

Can you measure the output of LM35DZ?

And from the voltage you measured,

what is the expected measured value of MCP3201?

Best Regards,

1-May-2020

Motoo Tanaka

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 Nasir-san,

I have just created an ADC sample to measure voltage around your circuit.

(I could measure from 0.001V to 4.999V at my side.

I assume that you are using CY8CKIT-059.

Please download attached project and use it to measure voltages.

GND and P0[0] must be connected to the target and its GND.

Then calculate expected values.

Best Regards,

1-May-2020

Motoo Tanaka

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

Dear Nasir-san,

Following is a schematic I drew from your description/code.

021-schematic.JPG

Currently the problem is the reading of SPI seems to be unstable.

This can happen because of

(A) Software problem inside the PSoC 5LP

(B) Data come from MCP3201/SPI is not stable

(C) Data come from LM35DZ is not stable

Since the reads of other sensors seem to be stable, I'd like to focus on (B) and (C)

Please try

(0) Make sure all the connection is stable and GND(Vss) of

     MCP1541, LM35DZ, MCP3201, and PSoC 5LP are all connected to the same ground plane.

(1) disconnect wire between MCP3201/Dout and PSoC/SPIMISO

     and connect PSoC/SPIMISO to GND.

    You should see the value 0x0000 (which you saw 0x0FFF last night)

(2)  If possible connect PSoC/SPIMISO to VDD via some resistor.

     You should see the value 0x0FFF

(3) reconnect  MCP3201/Dout and PSoC/SPIMISO.

If (1) (and/or (2)) fails there must be problem with PSoC 5LP and/or its software.

(4) disconnect wire between LM35DZ/Vout and MCP3201/IN+

     connect MCP3201/IN+ to GND

     You should see stable 0 or very low level value

(5) reconnect MCP3201/Dout and PSoC/SPIMISO.

if (1) (and/or (2)) is OK, but (4) fails there must be problem with MCP3201 or SPI communication.

In case (4) fails, I would strongly recommend you to use an Oscilloscope

and probe MCP3201's CLK, Dout, /CS with IN+ connected to GND

Best Regards,

1-May-2020

Motoo Tanaka

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 Nasir-san,

I tried your program slightly modified for print out with CY8CKIT-059.

(1) When SPIMISO is open/float

Note: This was the second run, the first run showed more random like behavior.

030-TeraTerm-float.JPG

(2) When I connected SPIMISO to GND

Note: This was the 2nd run, at the first run, the first 4 spi data was 0x0FFF.

Probably it was in the SPI RxBuffer.

031-TeraTerm-gnd.JPG

(3) When I connected SPIMISO to VDD

Note: This was the 1st run, so the first 4 words were still 0x0000 from the previous run.

But after them all the data was 0x0FFF

032-TeraTerm-VCC.JPG

So I think that at least the connection of SPIMISO has problem.

And pretty good chance that SPICLK and SPISS should be rechecked.

Best Regards,

1-May-2020

Motoo Tanaka

0 Likes

Dear Motoo Tanaka,

Thanks for all of your helps. I just found out the problem. It was needed to connect a 10uF capacitor to the Vout pin of

the MCP1541 voltage reference to get stable values. It was my mistake that I overlooked the datasheet information:

VR.PNG

I apologize that I wasted your tiime. Thanks again for all of your efforts.

temp.PNG

Best Regards,

Nasir Ahmed

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

Dear Nasir-san,

Thank you very much for the good news!

I'm so happy hearing that your circuit is now working!

Have a nice day!

Best Regards,

1-May-2020

Motoo Tanaka

0 Likes