In short - we have ADC (which emits information serially - a 12-bit binary word starting from MSB) and Arduino UNO. And we are interested in reading the information through the use of SPI.
The data that are critical to understand the situation are the sampling frequency of the ADC which is 1Msps and the input signal frequency to the ADC which is 10KHZ. We set up two arrays 20 in length, each of which is 8 bit in size.
We have some issues we encountered while writing the code and would be happy for help and guidance:
Using SPI.transfer we got that the command duration ranges from 4u to 8u. So the first question is what can cause these changes?
In reading the information from the ADC we have an 8-bit array even though the information waiting at the ADC output is 12-bit long - we do not mind so much as ignoring the lower 4-bit as long as we get a result that makes sense - but the question is what will be transmitted For an actual array? The high 8 bits or will some of the information be overwritten because we will start reading 8 bits and due to lack of space we will overwrite information we have already read?
We received a recommendation to use a buffer but could not figure out how it could help us exactly solve the problem - what we did in the code is not exactly a buffer?
The code is attached here. We will be happy to comment and explain what is wrong or what can be fixed.
Thanks.
The code:
#include <SPI.h>
byte Mastersend,Mastereceive[20];
//uint16_t Mastersend,Mastereceive[20];
void setup() {
pinMode(10, OUTPUT); // set the CS pin as an output
SPI.begin(); // initialize the SPI library
Serial.begin(115200);
Mastersend=0;
}
void loop() {
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
for(int i=0;i<20;i++){
digitalWrite(10, LOW); // set the CS pin to LOW
Mastereceive[i]=SPI.transfer(Mastersend);
digitalWrite(10, HIGH); // set the SS pin HIGH
}
SPI.endTransaction();
for(int i=0;i<20;i++){
Serial.println(Mastereceive[i]);
delayMicroseconds(1);
}
}
@davidaqua, please edit your post, select all code and click the </> button to apply so-called code tags and next save your post. It makes it easier to read, easier to copy and prevents the forum software from incorrect interpretation of the code.
How do you know? Your code does not show timing related information. Did you use an oscilloscope?
My experience with SPI is limited. If you send 20 bytes, you receive 20 bytes. The 20 received bytes contain 10 integers so you have to combine the first two bytes to create one reading, the next two bytes to create the next reading etc.
Which looks promising. It uses the RP2040 which is Arduino compatible and the same A/D you are wishing to utilize... all in one package. I did not dig into the availability, but that is a good starting point.
I'm not coming right out and saying the UNO is not capable, but it is an 8-bit device. Moving to something like the RP2040 at 32-bit is a quantum leap in capability.
If you are still on an UNO kick, good luck. You may achieve what you desire at the UNO's 16-MHz clock and limited SRAM, but you are likely going to have to dig very deep to get close to what you wish.
digitalWrite(10, LOW); // set the CS pin to LOW
unsigned long timeBegin = micros();
Mastereceive[i]=SPI.transfer(Mastersend);
unsigned long timeEnd = micros();
unsigned long duration = timeEnd - timeBegin;
Serial.print("duration is:");Serial.println(duration);
digitalWrite(10, HIGH); // set the SS pin HIGH
We measured using the code in the software and not using an oscilloscope. I enclose here a picture of the code we added and a result on the serial screen
The website dont allow me to add pictures but in the serial screen it shows me there are 3 transfer actions that takes 4us and the fourth action takes 8us and so on for the entire loop that appear in my question.
The site does not let new users upload media so I do not have how to show the results obtained in the serial plotter but we want to think that the changes between the times in the transfer operation make the signal appear abnormal so we want to know how to handle this problem.
. I agree with the stackexchange post--the code looks correct although I have not tested it--and I agree that most arduinos aren't fast enough to step on the acquistion time of the 33151, as it acquires very quickly.
I have written C code for RP2040 and the MCP33151 with 16Mhz SPI in "without busy bit" mode (see the datasheet for busy vs. "without busy" bit) and didn't have an issue, RP2040-C is a much faster environment than say INO AVR328P, which has a top SPI speed of 4Mhz.
For the code snippit linked, you may need to mess with the bit shift (>>2, >>3 etc) depending on what sort of accuracy you need. Again I have not tried it yet.