Can you show us your HW configuration to your RTD and Reference resistor? Is it a two-, three- or four-wire configuration?
I'm a bit confused with your current drive to the RTD and RefRes since you cannot drive the IDAC to both the RefRes and RTD at the same time with the Mux. Additionally, you are only using using Medium isolation.
Thank you for the schematic. Your two-wire schematic does not include the CurrentMux outputs. I've redrawn your Topdesign to include the external resistors to visualize the circuit better as a four-wire with the CurrentMux outputs driving the resistors. Please confirm this is an accurate representation.
I'll take a closer look at your application. I don't have a PT1000 RTD but I can emulate it.
Here's some additional notes:
- I changed your CurrentMux and ADCMux to AtMostOneActive = true and Isolation = Maximum. This is to try to prevent crosstalk between the RefRes and RTD circuits. Any crosstalk will share current with the other circuit will throw off your readings.
- Because you are using CurrentMux to switch to RefRes or RTD, there might be anywhere from 5 ohms to 2K ohms in routing resistance. If you consider the 2K then your measured voltage across RefRes or RTD can be as much as 1/3 the expected voltage. If you want to avoid the CurrentMux, see the suggestion I have shown below.
- In your application, turn off the IDAC source when not making a measurement. This minimizes resistor self-heating effects on the resistance value.
Here's a future suggestion:
Change to the following circuit. Advantages: Eliminates the CurrentMux and virtually guarantees the same IDAC current flowing through RefRes and RTD. It also minimizes routing losses especially if you use pins P0.6, P0.7, P3.0 or P3.1 for the the IDAC output.
I'm still unit testing your code. I do not have the actual HW and so I'm emulating the RefRes and RTD.
In my unit testing I replace the following with ideal values:
- IDAC = 1mA
- RefRes = 1000 ohm
- RTD = PT1000 resistance stepped from -70C to 90C. (Determined from the PT1000 table)
- RefRes_current_offset = 0 adc counts
- RTD_current_offset = 0 adc counts
When I use the above emulated values, I get the resultant Temp from RTD_GetTemperature() within 0.02C.
Once I use measured values for RefRes_current_offset and RTD_current_offset (from GetOffset()) the RTD_GetTemperature() is significantly off.
Since you have real circuit components, substitute a return value of 0 from GetOffset(). See if this improves your end temperature result.
As I indicated in an earlier post, there was a significant error source due to the offset measurement and compensation in GetOffset().
I changed the ADCMux to include a third channel with Vssa as the third input. Then in GetOffset() I don't change the IDAC but switch the ADCMUx to the Vssa channel (=2). This significantly lowers the GetResult32 value I was getting from 11000+ counts to < 1000 counts.
volatile int32 result = 0;
/* Set the ADCMux to VSSA to measure the ADC offset */
/* Get the ADC offset voltage */
result = ADC_GetResult32();
I believe you are trying to compensate for the ADC offset. Setting the IDAC to 0mA is not as effective since there are non-linearity and leakages in the IDAC output. I recommend this as a more preferred method to offset correct the ADC input.
Once I used the above technique for offset measurements, my Temp readings from RTD_GetTemperature() are now within 0.12C of the intended values. Note: My unit testing are still using ideal RefRes and RTD (stepped from -70C thru 90C) values.
1 of 1 people found this helpful
I've taken my unit tests to the next level. I populated a 1K resistor for RefRes. The ADC count I received is less than 2% of the expected value. I'm happy with that. I placed another 1K resistor on RTD (PT1000 value @ 0C). The ADC count is within 2% of expected and the RTD_GetTemperature() result is within 5%. Note: This is using my Vssa reference instead of setting the IDAC to 0mA.
I recommend that you perform some unit tests and validate that you get reasonable RefRes, RTD and RefRes_offset and RTD_offset ADC count values. You should be able to reasonably predict the ADC counts and either dump the raw ADC counts for each factor to the terminal or use the PSoC in debug mode to display the values.
Thank you for your lots of comments!
According to your comments, I checked a raw ADC value of reference resistor.
The output value was far different from the ideal value.
So, I changed a pin assignment of reference resistor from P3_1 and P3_2 to P3_5 and P3_6.
Then a calculated temperature of Pt1000 became a room temperature.
Thank you so much.
I'm glad you found a solution. I'm curious though why moving the pin assignments changed your results. Hmm ...