Hi all,
I need some guidance here. I'm new to SPI and am not having much luck getting the data I want. The set-up is a vectornav sensor connected to the 4 SPI pins on the arduino mega. And here's my not-so-polished code:
/*
code to read vectornav data via an arduino mega SPI pins
SPI mode uses a lightweight binary message format over the SPI data bus. The start of a command is signaled
by pulling the VN-100 module's chip select pin (pin 23) low. Both the chip select line and clock are active low.
The first byte transmitted to the module should be the command ID and then a variable number of bytes will
follow dependent on the type of command specified. A communication transaction can be cancelled at any time
by releasing the chip select pin. Pulling the pin low again will start a new communication transaction. All binary
data is sent to and from the chip with most significant bit (MSB) first in little-endian byte order with all
numbers either represented as 32-bit floating point or 32-bit unsigned integers. For example the serial baud
rate register with a value of 9600 (0x2580) would be sent across the SPI as a 0x80, 0x25, 0x00, 0x00. Data is
requested from and written to the device using multiple SPI transactions.
*/
#define DATAOUT 51 //MOSI
#define DATAIN 50 //MISO
#define SPICLOCK 52 //sck
#define SLAVESELECT 53 //ss
byte serialIn; // container to hold incoming serial data
byte clr;
byte attitude[16]; // yaw, pitch, & roll
unsigned long start_sample;
unsigned long end_sample;
unsigned long elapsed_time;
void setup()
{
Serial.begin(115200); // main UART pins
delay(500);
for (int i = 0; i < 16; i++) {
attitude[i] = i;
}
// SPI configs
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(SLAVESELECT,OUTPUT);
digitalWrite(SLAVESELECT,HIGH); //disable device
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 rate (fastest)
SPCR = B01010000; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (4MHzHz)
clr = SPSR;
clr = SPDR;
delay(500); // everyone else is doing it; i am a lemming
} // end setup
void loop() {
// check UART pin for any incoming data
if (Serial.available() > 0) { // mail call
serialIn = Serial.read();
// let's take a some sample
if (serialIn == 33) { // = ! = time to start sampling
// 01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00
digitalWrite(SLAVESELECT,LOW);
attitude[0] = spi_transfer(0x01);
delayMicroseconds(100);
attitude[1] = spi_transfer(0x08);
delayMicroseconds(100);
attitude[2] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[3] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[4] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[5] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[6] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[7] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[8] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[9] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[10] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[11] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[12] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[13] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[14] = spi_transfer(0x00);
delayMicroseconds(100);
attitude[15] = spi_transfer(0x00);
delayMicroseconds(100);
digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
for (int i = 0; i < 16; i++) {
Serial.print(attitude[i], BYTE);
}
Serial.print(10, BYTE);
} // end sample if/then
} // end UART while loop
}
byte spi_transfer(volatile byte data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
return SPDR; // return the received byte
}
So with the above code I'm just trying to get attitude vales (heading, pitch, roll). The message I'm sending (in hex) is:
01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00
what I should get back should be something like:
00 01 08 00 39 8A 02 43 FD 43 97 C1 CD 9D 67 42
(the last 12 bytes = -130.54, -18.91, +57.90)
What I'm getting is:
1 128 0 0 0 0 0 0 0 0 0 0 0 0 0 0
or
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I feel like I'm close since it's at least writing over my init values for the array, but after a couple days of reading up on SPI I'm a bit at a loss at what to try next, or if there is an error in my code or ??
Any advice? Also FYI I can communicate just fine via the UART pins (one of the reasons why getting the mega), but was looking for a faster method for getting data out of the sensor.
TIA,
David