Hi, I need to send data over Serial communication to Arduino MKR Zero board which will send this data over SPI to an SPI controlled potentiometer. The data size is 16 bits or 2 bytes. I can only send the data from my PC over the Serial communication as integers (due to the limitation of using markers in my serial communication) so the value will range from 0 to 65,535 (i.e. from 1 to 5 characters with each character representing one digit). How can I convert this data to a 16-bit value so that I can it send to my potentiometer using SPI.transfer16() function?
My current solution:
int receivedData = atoi(charData); // to convert to integer, charData is a char array containing the received digits from PC
unsigned int val = (unsigned int)receivedData;
/* or */
uint16_t val = receivedData;
I am not sure which one would give me exact 16 bits as documentations for uint16_t is not present in Arduino Reference and unsigned int can be both 16-bit (Uno and ATMEGA) and 32-bit (Due) while MKR Zero is SAMD based.
Is there a better/simpler way to convert an integer into exactly 16-bit value?
With your board, unsigned int will still be 32 bits
You can use "uint16_t", or "unsigned short"
But, I don't think there will be a problem if you use SPI.transfer16() directly with your int, it will just take the first 16 bits and discard the rest
guix:
But, I don't think there will be a problem if you use SPI.transfer16() directly with your int, it will just take the first 16 bits and discard the rest
If I convert anything in between 0 to 65535 to a 32-bit int, then the first 16 bits will be zero. So if I am sending the 32-bit int directly using SPI.transfer16() function then won't it send all zeros?
In Arduino UNO, the following sketch provides exactly 16-bit natural binary for the decimal charcaters received from the InputBox of Serial Monitor. (65535 ----> FFFF; 65000 ----> FDE8)
char myData[15];
void setup()
{
Serial.begin(9600);
}
void loop()
{
byte y = Serial.available();
if(y !=0)
{
byte m = Serial.readBytesUntil('\n', myData, 10);
myData[m] = '\0';
unsigned int x = atoi(myData);
Serial.println(x, HEX);
memset(myData, 0, 10);
}
}
Better to say "least significant 16 bits", as there's no notion of ordering other than by
significance of each bit.
When, in C/C++, integer types are widened or narrowed the least significant bits stay
as they are and silent truncation may happen. Widening of signed integers will sign-extend,
widening of unsigned integers will zero-extend.