SPI slave randomly missing bits in response
Ask QuestionAsked 5 days agoActive todayViewed 98 times1
I’ve connected an MCP3008 to a raspberry pi. First on a solderless breadboard, where everything worked correctly. Then on a prototyping board, where the only difference is that the chip is externally powered. The problem is now that the response from the slave is occasionally missing bits (the slave fails to pull the signal up for every bit that it should). Here is a series of readings taken at a 0.01 s interval:
[3.4, 3.39, 3.29, 0.0, 3.4, 3.4, 3.4, 2.55, 0.0, 2.98, 3.39, 0.0, 3.39, 3.3, 3.19, 3.4, 2.98, 3.4, 3.4, 0.58]
The readings are normalized for Vref = Vin = 3.4.
I’ve tried:
- Redoing the soldering,
- replacing the MCP3008,
- adjusting the SPI frequency (currently at 1.35 MHz),
- checking the connections and voltages using a multimeter
- using the piscope to examine the serial communication (tricky, because if I set the frequency low enough to get a good reading, the chip rarely returns any values at all)
- grounding unused inputs
The PCB has copper wire from the header to the chip for the SPI interface, about 5cm long. As far as I can see, that should be fine for SPI. SpiDev is set to use mode 0.
Any other ideas as to what might be going wrong would be hugely appreciated.
Update:
Connecting the Raspberry Pi ground to the external ground solved the issue, so it looks like the lack of common reference voltage caused the mcu to sometimes not pull high above the necessary threshold.adcraspberry-pispishareedit follow flagedited Aug 7 at 6:50asked Aug 6 at 22:10boileau11555 bronze badges New contributor
- 2Time for a real scope … – Tom L. Aug 6 at 22:17
- 3Decoupling caps? – DKNguyen Aug 6 at 22:20
- 1I have caps on all the inputs, same as on the breadboard. – boileau Aug 6 at 22:26
- 1@TomL. Yeah, I think I’ll finally have to bite the bullet and pick up an oscilloscope. But in this case it will only rule out bad wiring, I think. – boileau Aug 6 at 22:28
- 1@boileau It could show a noise issue, connection instability, or brownout. You said in your post that you’re missing bits, but your 3.4V readings show that you’re missing entire bytes. Which is it? – DKNguyen Aug 6 at 23:10
- 1do you have components available to go back to solderless breadboard? … if you do have the components, then go back to a working version and switch to external power supply – jsotola Aug 7 at 0:14
- 1@DKNguyen if an entire byte is missing, then bits are necessarily missing (8 to be precise). – boileau Aug 7 at 6:40
- @jsotola I don’t because I managed to short 24V through the first mcu. That would have been my next step otherwise. – boileau Aug 7 at 11:51
- @boileau They are different problems. Failing to assert an entire random bytes is different than failing to assert random individual bits. – DKNguyen Aug 7 at 13:09
1 Answer
Question
The OP is testing MCP3008 with SPI speed 1.35MHz, and found results inaccurate. How come?
Answer
Update 2020aug12hkt1148
The OP mentions that he is using more than one MCP3008 to do swap troubleshooting. I always do swapping testing and troubleshooting, but I usually use samples from two shops, because from time to time I find that the whole lot I buy from one shop is bad. The other thing is that eBay shops are not always good. I usually buy from manufacturer’s authorized shop (eg MicroChip authorized shop at TaoBao).
Now I am writing just one python program to calibrate all three ADCs, MCP3008, MCP3201, and MCP3208. I can actually calibrate all three at the same time with different SPI ports, each with multiple readings, with max, min, mean, and error values. MCP3008, MCP3201, and MCP3208 have the same SAR ADC architecture, and the SPI commands are extremely simple and newbie friendly, there is no need to access any device register, making one conversion is as simple as reading three bytes for MCP3008, MCP3208, and only two bytes for MCP3201, as illustrated below.

Update 2020aug11hkt2116
The OP has found that improper grounding causes inaccurate conversion results. I might also investigate the effect of using digital ground vs analog ground or Vcc ground etc.
But I think the most important factor of conversion accuracy is SPI speed. I know 4MHz might be the upper limit, but I am interested to know if 2MHz or 1MHz is optimum, or if I should use even lower, perhaps 400kHz and 100kHz for higher reliability.
My test plan now is to first try one channel MCP3201 because the wiring and software is very simple, and techniques acquired can easily scale up to 8 channel MCP3208 and MCP3008.
I am starting the prototype hardware without any by pass caps for both Vcc and Vref. If I find results bad, then I will add bypass caps to compare and contrast.

Update 2020aug10hkt1652
My incomplete answer has inspired the OP to find the solution himself, as explained in his edit.
I am learning more things that might cause noise problems and inaccurate measurements, eg how to use bypass caps to stabalise the reference voltage source (ref 4), as illustrated below:

Update 2020aug07hkt1219
Now I am searching my old lab log to hopefull find something useful to suggest the OP to troubleshoot. I read my old schematic and found two things the OP might consider.
(1) Use separate analog grounds and digital grounds, as shown in the schematic below.
(2) Use a digital voltage reference with small series resistance, to maximize sample and hold capacitor current, so to prevent the not enough time filling up at high frequencies.
(3) Use one differential input channel, instead of single ended, to avoid noise problems. The three other not used differential inputs should be grounded, also to prevent noise, (ESD, back EMF) surge/spike problems.
(4) The schematic also reminds me that MCP3008’s Chip Select (CS) pin is also used to “Shut Down”. The Op might not be aware that there shutting down might need some time to wake up, otherwise the next conversion might not be accurate. This is just brainstorming, and I have not looked into this minor details for these particular hip, but I do have annoying experiences of not being aware that some chips’s initialization and waking up take a long time, in the order of milliseconds.

(5) One more thing is that the OP is powering MCP3208 with 5V. In this case Rpi 3V3 logic SPI signals should NOT directly drive 5V device. I almost always do not use directly Rpi’s 3V3 GPIO/UART/I2C/SPI signals. I always shift up Rpi’3 3V3 signals to 5V (using TSX/TBX0102/4/6/8)
I forgot if there is any other precautions things I need to observe. So I searched my reading logs and found the following:

Update 2020aug07hkt1149
I made a careless mistake in reading the datasheet, resulting a wrong conclusion. Please ignore this wrong answer. I will try to improve my answer later. My apologies.
Part A – Datasheet spec summary
A.1 – max data rate = 20ksps (Errata – should read 200ksps).
A.2 – conversion time = 3 SPI byte transactions, or 24 cycles.
Part B – Circuit analysis
B.1 – Example Case 1 : SPI Frequency = 1MHz, => conversion time = 24us.
B.2 – Max sps = 1/24us ~= 40kHz.
B.3 – Conclusion: 1MHz means 40ksps is too high for MCP3008 to handle.
Errata – Conclusion is wrong. Max sps of 200ksps should imply max SPI frequency around 4MHz
Part C – Troubleshooting suggestions
C.1 – Suggest to lower SPI frequency from OP’s 1.35MHz to 100kHz (Note 1) and test again.
Notes
N.1 – Spec says min frequency > 10kHz, or sample and hold cap leaks.
N.2 – Volt source Rs < 1k, or sample and hold cap input current too small to fill up in time.
N.3 – Using SPI frequency might have a same trouble as N.2 above: sample and hold cap does not have enough time to fill up.
N.4 – My always dodgy calculation is not proofread.
References
(2) MCP3008 for Rpi Tutorial – M Sklar, AdaFruit, 2019jul
(3) MCP3008 ADC readings not accurate Problem – tlfong01, rpi.stackexchange 2029may 22
(4) Bypass cap on reference voltage? – EE SE 2020aug09
Appendices
Appendix A – MCP3008 Operation

Appendix B – The OP’s missing bits in his MCP3008 ADC Conversion Results
I was curious which bits were missing. So I converted the decimals to binary to try to find a clue.
dec 3.40 = bin 11.01100110011001100110
dec 3.39 = bin 11.01100011110101110001
dec 3.30 = bin 11.01001100110011001101
dec 3.29 = bin 11.01001010001111010111
dec 3.19 = bin 11.00110000101000111101
dec 2.98 = bin 10.11111010111000010100
dec 2.55 = bin 10.10001100110011001101
dec 0.00 = bin 0.000000000000000000000
My thought for 15 seconds and jumped to the conclusion that the missing bits should be random, so I give up diving deeper.
End of answershareeditdeleteflagedited just nowanswered Aug 7 at 3:29tlfong0143733 silver badges66 bronze badges
- 1Wow, thanks for the answer. It inspired me to connect the raspberry pi ground to the external ground. Doing that solved the issue! – boileau Aug 7 at 5:25
- @boileau, How nice to hear that you have found the solution. By the way, I appreciate very much the way you present the problem concisely but still with all the necessary helpful details. It has been a pleasure learning problem solving with you. Have a great project. Cheers. – tlfong01 Aug 7 at 8:19
- 1Thanks for the feedback. I’m hoping the shared ground bit helps someone else. My own googling didn’t lead me to anything useful. – boileau Aug 7 at 11:53
- Yes, even your question with the detailed troubleshooting history help newbies a lot. BTW, I am finding more and more things that I didn’t know that I didn’t know, eg. how to by pass the reference voltage. So I am adding more troubleshooting tips from time to time. Have a great project. Cheers. – tlfong01 yesterday
.END
Categories: Uncategorized