I'm having a problem deciding if the PlainADC example will work correctly.
// In the declaration section
uint8_t *vData = NULL; // Pointer variable to integer data array
// In the setup section
vData = pADC.SetAcquisitionEngine( ADC_PIN, ADC_REF_VOL_DEFAULT, SAMPLE_RATE, SAMPLES, ADC_DAT_FMT_INT );
// Which requests 512 integers from the ADC
My confusion is that the pointer appears to be for 8-bit data but I need to access 512 integers. The PlainADC library returns a uint8_t pointer. The compiler complains if I ask for a uint16_t pointer as I think I should have.
I've sent an email to Didier but no answer yet.
Are your samples 8 or 16 bits? If they are 8 bits, you shouldn't use a pointer to a uint16_t type. The correct data type to represent the number of samples can be determined by looking at the fourth parameter of the function prototype of SetAcquisitionEngine() in the library header file.
In SetAcquisitionEngine() arg 4 & 5, I am asking for 512 samples of integer data. That is why I think I need a uint16_t pointer. However, the library wants to return only a uint8_t pointer. If I use this then I think I'll only get the first 256 bytes or 128 integers in a high byte-low byte sequence.
Can I cast the uint8_t pointer to a uint16_t pointer then access my data one integer at a time by incrementing the pointer value by 1, or an index i in a for loop?
You don't understand pointers. All pointers on the AVR are the same size, no matter what they point to. The issue you are talking about does not exist.
What do I need to do to access 512 integers?
Arctic_Eddie:
I'm having a problem deciding if the PlainADC example will work correctly.
...
My confusion is that the pointer appears to be for 8-bit data but I need to access 512 integers. The PlainADC library returns a uint8_t pointer. The compiler complains if I ask for a uint16_t pointer as I think I should have.
http://snippets-r-us.com/
How to use this forum
What do I need to do to access 512 integers?
First, that's a lot of integers. But if you want a pointer to them:
int myIntegers[512]; // An int array
int *ptr; // to work with an int array, it must be an int pointer
void setup() {
int i;
Serial.begin(9600);
for (i = 0; i < 512; i++) { // Stuff the array
myIntegers[i] = i;
}
ptr = myIntegers;
for (i = 0; i < 512; i++) { // Walk thru the array with ptr
Serial.println(*ptr++);
}
}
void loop() {
}
Note the type specifier for ptr. As aarg pointed out, the memory requirement for any pointer on an Arduino is 2 bytes. However, using this pointer:
char *cptr;
in the statement:
cptr++;
increments the value of the pointer by 1. However, the statement:
ptr++;
increments the value of the pointer by 2. The reason is because the pointer must move over 2 bytes to read the next integer in the array. If it is a char pointer, it only needs to move over 1 byte. So, while all pointers require two bytes of storage, their math operations (e.g., ++ or --) must be scaled to the data type that was defined for the pointer.
Look at the code in my first post. The problem is that the pointer returned from the ADC initialize is for 8-bit data but the stored array is 16-bit. I have no control over that part as it's in the library code. I found an example that may have solved the problem.
uint16_t *vInt16Data = reinterpret_cast<uint16_t*>(vData);
I have not run it yet but the compiler does not complain. The original example recast the pointer into a double. The initialize asked for double data but the pointer was 8-bit.
Thanks for the insight to all those that commented.
I was blindsided by your terminology. You said "integer". uint8_t is an integer, int is an integer, long is an integer type. All integers. If you mean int, say int.
If the samples are truly 16 bits, I don't grasp the reason for accessing them a byte at a time. If you want to look at high and low bytes of a sample, can't you just dereference a uint16_t, and then perform a separation operation? It would be more straightforward in general (because a single sample is a logical data unit).
I'm locked into the code in the PlainADC library. The ADC initialize asks for 512 integers of type uint16_t but the pointer returned can only be uint8_t due to the library. I want to retrieve my data as uint16_t via the pointer. The reinterpret_cast statement in my last post appears to solve the problem.
If the following statement is true then I have a better understanding of pointers.
"The type of a pointer has to match the data structure it points to and not the quantity that can be accessed."
I'm sorry that I misunderstood. Do you have a web link to the library?
Unfortunately, no. I acquired the ADC and FFT libraries by direct email request several years ago. He no longer supplies those two libraries but has included them in PlainDSP with an Arduino Uno shield. The data is in the link.
PlainDSP
Buried in his example library, I found the usage of the "reinterpret_cast" function which he used to convert the uint8_t pointer to a double. The data was collected as double so he had to recast the pointer. I just changed the double terminology to uint16_t and hope it works. The compiler does not complain so there is hope.
If the pointer type has to match the data type it points to then my understanding is clearer now.
Arctic_Eddie:
If the pointer type has to match the data type it points to then my understanding is clearer now.
If the library author had made it a void pointer, it would have reflected the intended usage better, and the error message would have been slightly more suggestive of the solution. Because then, a pointer cast would always have been required, which in this case is probably a good idea.
But there is probably a higher level solution that irons out such difficulties.
I'm testing the pointer cast method now and have discovered that the high speed ADC routine does not work on the Nano but will on the Uno. I'll have to rethink the project as I need four Arduinos collecting sonar data from a 4x4 array of sensors then sending it to a Mega via I2C then to a shore station via RF24 radio link. I can make it work with the cast method and his example.
Thanks to all posters for the help. I understand the situation much better now.