- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
I apologize that I wasted your tiime. Thanks again for all of your efforts.
Best Regards,
Nasir Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Please read Page 21 of the MCP3201 Datasheet
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
(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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Motoo Tanaka,
Now I see, I am getting too big numbers. Here is the picture:
Any idea, why?MoTa_728816
Best Regards,
Nasir Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi MoTa_728816,
Now I am getting this:
And a Warning says: "data argument not used by format string":
nasir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear MoTa_728816,
I checked the connection of SPICLK, SPISS, SPIMISO, and GND and they are correctly connected.
Best Regards,
nasir
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi MoTa_728816,
As you said I connected MISO signal to GND and got 0x0FFF
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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Nasir-san,
Following is a schematic I drew from your description/code.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
(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.
(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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
I apologize that I wasted your tiime. Thanks again for all of your efforts.
Best Regards,
Nasir Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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