srivathsa92:
I'm using an Arduino Uno to read in data from a DMU02. This is my first time using SPI, and I'm having difficulty figuring out how to read from the DMU02 and output the data in the Serial Monitor. The IMU has 3 slave ports, and by turning 1 out of the 3 from HIGH to LOW I can access the Gyroscope, Magnetometer, and Accelerometer. Just going off the help I've found online, I've written a bit of skeleton code and I was hoping I could get some insight on how to get the data out of the IMU.
please use the code tags </> around your code
I have inserted critiques to your code below:
//
#include <SPI.h>
/* unnecessary defines
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO
#define SPICLOCK 13 //CLK
*/
#define S1 7 //Slave 1
#define S2 6 //Slave 2
#define S3 5 //Slave 3
void setup() {
Serial.begin(9600);
//Initialize input and outputs
/* Unnecessary, the SPI.begin() will do this.
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
*/
// but you should set SS (digital 10) to output, When using the SPI hardware, if (digital pin 10),SS is
// ever set as an INPUT, and it goes LOW, the next call to SPI.transfer() will hang forever. The SPI
// hardware will switch to SPI Slave mode, and It will nolonger drive CLK, It will accept CLK from the
// 'other' SPI Master device one the bus.
pinMode(SS,OUTPUT);
digitalWrite(SS,HIGH); // this doesn't really matter, but SS should be OUTPUT whenever SPI is used.
// you could us SS, digital pin 10, as one of your 'Sx' pins.
pinMode(S1,OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
//raise all the slave selects high
digitalWrite(S1,HIGH);
digitalWrite(S2,HIGH);
digitalWrite(S3,HIGH);
SPI.begin(); // Initialize SPI parameters
SPI.setBitOrder(MSBFIRST); // MSB to be sent first
SPI.setDataMode(SPI_MODE3); // Set for clock rising edge
}
void loop()
{
int val=0; //test variable used when reading pins
int j=0; //variable used in data read operation
byte pot=B00000000; //zero out all the values in the byte, where data will be written to
for (int i=0; i<2;i++)
{
j=i+1;
val=digitalRead(j);
if(val==HIGH)
{
bitSet(pot,i);
i++;
/*
why are you messing with the for loop value?
here is what your code actually does:
if val is HIGH
then bitSet(pot,i),
then increment i,
then the for loop incriments i again
then the for loop test i <2, which always fails
*/
}
// Here is my rewrite of this for loop
// also you should have set digital pins 1..2 as input (pinMode(1,INPUT); pinMode(2,INPUT);
byte pot=B00000000; //zero out all the values in the byte, where data will be written to
for (int i=0; i<2;i++) {
if(digitalRead(i+1)) pot = pot | (1 << i);
/*
explaination:
(1 << i) means create a value by shifting 1, i binary places to the left
pot | (1 << i) means take the value of pot and 'OR' it with the value of (1 << i),
so if pot =0, and i =0 then pot become 1;
if pot =0 and i =1 then pot = B00000000 | B00000010 = B00000010 = 2
if pot = 2 and i= 0 then pot = B00000010 | B00000001 = B00000011 = 3
*/
}
digitalWrite(S1, LOW);
SPI.transfer(pot); // this command just sent
// the Device will do nothing, because it is expecting a 6 byte command sequence with cksum.
digitalWrite(S1, HIGH);
Serial.print(pot);
delay(1000);
}
//
Here is my code to read an axis;
#include <SPI.h>
#define axisX 2 // connect digital pin 2 GND to read X axis
#define axisY 3 // connect digital pin 3 GND to read Y axis
#define axisZ 4 // connect digital pin 4 GND to read Z axis
#define S1 7 //Slave 1
#define S2 6 //Slave 2
#define S3 5 //Slave 3
void getAxisData( uint8_t axisPin){
uint8_t cmd[6],data[6]; // buffers for SPI data
cmd[0] = 1; // get rate and Acceleration data
cmd[1] = 0; //reserved
cmd[2] = 0; //
cmd[3] = 0; //
cmd[4] = 0; //
cmd[5] = ~(cmd[0]+cmd[1]+cmd[2]+cmd[3]+cmd[4]); // one's complement of Sum (0..4)
switch(axisPin){
case axisX : digitalWrite(S1,LOW);
break;
case axisY : digitalWrite(S2,LOW);
break;
case axisZ : digitalWrite(S3,LOW);
break;
default :
Serial.print("unknow Axis =");
Serial.println(axisPin,DEC);
return;
}
for(int i=0;i<6;i++){
data[i] = SPI.transfer(cmd[i]);
}
switch(axisPin){
case axisX : digitalWrite(S1,HIGH);
break;
case axisY : digitalWrite(S2,HIGH);
break;
case axisZ : digitalWrite(S3,HIGH);
break;
default : // can never get here, the first switch statement would have exited
Serial.print("unknow Axis =");
Serial.println(axisPin,DEC);
return;
}
Serial.print(" Rate and Accel for Axis pin=");
Serial.println(axisPin,DEC);
for(int i =0;i<6;i++){
Serial.print("data[");Serial.print(i,DEC); Serial.print("]= B");Serial.println(data[i],BIN);
}
Serial.println();
}
void setup() {
Serial.begin(9600);
//Initialize input and outputs
pinMode(SS,OUTPUT);
digitalWrite(SS,HIGH); // this doesn't really matter, but SS should be OUTPUT whenever SPI is used.
pinMode(axisX,INPUT_PULLUP); // connect weak pullup on input pin, 'switch' is active 'LOW'
pinMode(axisY,INPUT_PULLUP); // connect weak pullup on input pin, 'switch' is active 'LOW'
pinMode(axisZ,INPUT_PULLUP); // connect weak pullup on input pin, 'switch' is active 'LOW'
pinMode(S1,OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
//raise all the slave selects high
digitalWrite(S1,HIGH);
digitalWrite(S2,HIGH);
digitalWrite(S3,HIGH);
SPI.begin(); // Initialize SPI parameters
SPI.setBitOrder(MSBFIRST); // MSB to be sent first
SPI.setDataMode(SPI_MODE3); // Set for clock rising edge
}
unsigned long timeout=0;
loop(){
if (millis()>timeout){ // limit the rate of message to Serial monitor
timeout = millis() + 1000; // once per second;
for(int i = axisX;i<=axisZ;i++){
if(!digitalRead(i) ) getAxisData(i); // if input is low then read axis data
}
}
}
try this code, I haven't complied it, there may be some syntax errors
Chuck.
Check out my Kickstarter Project Memory Panes an expansion RAM Shield for Mega2560's. It adds 1MB of RAM for those projects where 8KB is not enough.