Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMU, barometer data #1

Open
dheera opened this issue Feb 10, 2019 · 8 comments
Open

IMU, barometer data #1

dheera opened this issue Feb 10, 2019 · 8 comments

Comments

@dheera
Copy link

dheera commented Feb 10, 2019

Hi,
Could you please provide an example of how to read 9-axis IMU and barometer data on an Aerocore2 for Jetson? It is not clear from the documentation exactly which pins are connected to the gyro, which pins are connected to the compass, and which are the CS pins for the barometer and IMU modules. The online interface shows all 3 modules being connected to SPI3 but no CS pins. Thanks.

@GumstixExperimental
Copy link

The STM32 on the Aerocore 2 is usually loaded with our NuttX based PX4 firmware for MAV operation. The Arduino AutoBSP is a recent addition so example code is not yet available. In the meantime, the board is configured as such:

Pin - Signal Name - Device
PE2 - SPI3_CS0 - LSM303D (Accel/Mag)
PE3 - SPI3_CS1 - L3GD20H (Gyr)
PE4 - SPI3_CS2 - MS5611 (Baro)

@dheera
Copy link
Author

dheera commented Feb 13, 2019

@GumstixExperimental Thanks! Is there any wiring or interface between the STM32 and the TX2? Or is the only way to pass data between the two to crosswire their UARTs?

(I'm using this for a robot, not a MAV, so I want all sensor raw data getting passed directly to the TX2 for now.)

@leekeith
Copy link

The TX2 and the STM32 are connected via on-board UART and SPI connections. See the attached autodoc for reference. The "UART-UART" and "SPI Bridge" modules are the points of interest here.
CS is PB12 on the STM32 and SPI2_CS0 (G16 on the connector) on the Jetson

ac_jetson_autodoc.pdf

@dheera
Copy link
Author

dheera commented Feb 14, 2019

Thanks @leekeith -- this is helpful. I do wish there were some more human-written documentation rather than the auto-generated one that included information such as the SPI CS pins that I had to ask for above.

Another question for @GumstixExperimental that is unrelated but thought you might know -- I'm having issues getting the UART on the Jetson to work. I tried jumpering TX to RX and I get no echo on /dev/ttyTHS1, /dev/ttyTHS2, or /dev/ttyTHS3 (not sure which one it is supposted to be). I notice that in the web interface it is wired to UART3. On the NVIDIA forum (https://devtalk.nvidia.com/default/topic/985665/jetson-tx1/how-to-use-tx1-uart3/) It is said that UART3 is inaccessible. Could this be a hardware bug?
2019-02-14 07 23 53

@dheera
Copy link
Author

dheera commented Feb 15, 2019

@GumstixExperimental I still haven't gotten the TX2's UART header to work (see above).
However I did succeed in getting /dev/ttyTHS2 to receive data from the STM32.

Questions however:

  • I am not able to receive data from the IMU. I'm using SPIClass spi(PIN_SPI3_MOSI, PIN_SPI3_MISO, PIN_SPI3_SCK); -- please confirm this is correct.
  • Could you pease double check the CS pins specified above? PE4 is not defined in the headers at all. I'm not getting data from IMU or Gyro using the CS pins above and standard example code from reading from those sensors.

Thanks!

@dheera
Copy link
Author

dheera commented Feb 15, 2019

By the way I notice PIN_SPI3_MISO, PIN_SPI3_MOSI are defined twice in variant.h:

#define SPI4_DEV_FRAM 
#define PIN_SPI3_SCK 30
#define UNKNOWN_PE3 32
#define PIN_SPI3_MISO 33
#define PIN_SPI3_MOSI 34

#define SPI3_DEV_ST_IMU 
#define SPI3_DEV_BAROMETER 
#define PIN_SPI3_SCK 49
#define PIN_SPI3_SS 50
#define PIN_SPI3_MISO 51
#define PIN_SPI3_MOSI 52

@dheera
Copy link
Author

dheera commented Feb 15, 2019

Update: I found the constants were defined wrong. This code works to read accelerometer, magnetometer, and gyro. However I find the accelerometer data is very erratic and jumps between roughly -1.0 g and 0.0 g with the board stationary. Gyro readings seem OK. Magnetometer readings I could not verify. Has this problem been observed before?

#include <Wire.h>
#include <HardwareSerial.h>
#include <SPI.h>

#define HAVE_HWSERIAL7
#define HAVE_HWSERIAL3
#define HAVE_HWSERIAL2
#define HAVE_HWSERIAL1

//SPIClass spi(PIN_SPI3_MOSI, PIN_SPI3_MISO, PIN_SPI3_SCK); // DOESN'T WORK
SPIClass spi(PC12, PC11, PC10); // works

SPISettings spi_cfg(14000000, MSBFIRST, SPI_MODE0); 

extern SPIClass spi;
extern SPISettings spi_cfg;

// chip select pins
#define CS_ACC PE2
#define CS_GYR PE3
//#define CS_BAR PE4 // DOESN'T WORK (PE4 not defined in variants.h)

// LSM303D registers
#define OUT_X_L_M   0x08
#define OUT_X_H_M   0x09
#define OUT_Y_L_M   0x0A
#define OUT_Y_H_M   0x0B
#define OUT_Z_L_M   0x0C
#define OUT_Z_H_M   0x0D
#define CTRL1       0x20
#define CTRL2       0x21
#define CTRL5       0x24
#define CTRL7       0x26
#define OUT_X_L_A   0x28
#define OUT_X_H_A   0x29
#define OUT_Y_L_A   0x2A
#define OUT_Y_H_A   0x2B
#define OUT_Z_L_A   0x2C
#define OUT_Z_H_A   0x2D
#define TEMP_OUT_L  0x05
#define TEMP_OUT_H  0x06
// gyro registers
#define OUT_X_L     0x28
#define OUT_X_H     0x29
#define OUT_Y_L     0x2A
#define OUT_Y_H     0x2B
#define OUT_Z_L     0x2C
#define OUT_Z_H     0x2D


void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
 
  while(!Serial);
  
  Serial1.begin(9600); // gps
  Serial3.begin(57600); // jetson
  Serial2.begin(9600); // header left
  Serial7.begin(9600); // header right
  pinMode(PE9, OUTPUT);
  pinMode(CS_ACC, OUTPUT);
  pinMode(CS_GYR, OUTPUT);
  //pinMode(CS_BAR, OUTPUT);
  digitalWrite(CS_ACC, HIGH);
  digitalWrite(CS_GYR, HIGH);
  //digitalWrite(CS_BAR, HIGH);

  spi.begin();
  writeReg(CS_ACC, CTRL1, 0b01010111);
  writeReg(CS_ACC, CTRL2, 0b01010000);
  writeReg(CS_ACC, CTRL5, 0xf4);
  writeReg(CS_ACC, CTRL7, 0b00000000);  
  
  writeReg(CS_GYR, CTRL1, 0x0F);
}

int8_t readData   = 0x80;
int8_t writeData  = 0x00;

int8_t readReg(int8_t CS, int8_t address) {
  int8_t buffer = 0;
  digitalWrite(CS, LOW);
  delayMicroseconds(100);
  spi.beginTransaction(spi_cfg);
  spi.transfer(readData | address);
  buffer = spi.transfer(writeData);
  spi.endTransaction();
  digitalWrite(CS, HIGH);
  return(buffer);  
}

void writeReg(int8_t CS, int8_t address, int8_t val) {
  digitalWrite(CS, LOW);
  delayMicroseconds(100);
  spi.beginTransaction(spi_cfg);
  spi.transfer(writeData | address);
  spi.transfer(val);
  spi.endTransaction();
  digitalWrite(CS, HIGH);
}

bool ledState = false;
void loop() {
  // flash LED
  ledState = !ledState;
  digitalWrite(PE9, ledState);
  
  // read registers
  int16_t ax, ay, az;
  int16_t mx, my, mz;
  int16_t gx, gy, gz;
  
  mx = (int16_t) readReg(CS_ACC, OUT_X_H_M) <<8 | readReg(CS_ACC, OUT_X_L_M);
  my = (int16_t) readReg(CS_ACC, OUT_Y_H_M) <<8 | readReg(CS_ACC, OUT_Y_L_M);
  mz = (int16_t) readReg(CS_ACC, OUT_Z_H_M) <<8 | readReg(CS_ACC, OUT_Z_L_M);
  
  ax = (int16_t) readReg(CS_ACC, OUT_X_H_A) <<8 | readReg(CS_ACC, OUT_X_L_A);
  ay = (int16_t) readReg(CS_ACC, OUT_Y_H_A) <<8 | readReg(CS_ACC, OUT_Y_L_A);
  az = (int16_t) readReg(CS_ACC, OUT_Z_H_A) <<8 | readReg(CS_ACC, OUT_Z_L_A);
  
  gx = (int16_t) readReg(CS_GYR, OUT_X_H) <<8 | readReg(CS_GYR, OUT_X_L);
  gy = (int16_t) readReg(CS_GYR, OUT_Y_H) <<8 | readReg(CS_GYR, OUT_Y_L);
  gz = (int16_t) readReg(CS_GYR, OUT_Z_H) <<8 | readReg(CS_GYR, OUT_Z_L);

  // print to jetson-facing UART

  Serial3.print("M"); Serial3.print("\t");
  Serial3.print(mx); Serial3.print("\t");
  Serial3.print(my); Serial3.print("\t");
  Serial3.print(mz); Serial3.print("\t");
  
  Serial3.println();
  
  Serial3.print("A"); Serial3.print("\t");
  Serial3.print(ax); Serial3.print("\t");
  Serial3.print(ay); Serial3.print("\t");
  Serial3.print(az); Serial3.print("\t");

  Serial3.println();
  
  Serial3.print("G"); Serial3.print("\t");
  Serial3.print(gx); Serial3.print("\t");
  Serial3.print(gy); Serial3.print("\t");
  Serial3.print(gz); Serial3.print("\t");
  
  Serial3.println();
  Serial3.flush();
}

@dheera
Copy link
Author

dheera commented Feb 16, 2019

Update: This code works in reading values, but I had issues with the magnetometer being stuck at 3.125 Hz despite being set to 50Hz or 100Hz, and the gyroscope being stuck at one reading. Accelerometer worked fine.

I think I'm giving up on this IMU and just plugging a BNO055 into the I2C port.

#include <Wire.h>
#include <HardwareSerial.h>
#include <SPI.h>

#define HAVE_HWSERIAL7
#define HAVE_HWSERIAL3
#define HAVE_HWSERIAL2
#define HAVE_HWSERIAL1

//SPIClass spi(PIN_SPI3_MOSI, PIN_SPI3_MISO, PIN_SPI3_SCK); // DOESN'T WORK
SPIClass spi(PC12, PC11, PC10); // works
SPISettings spi_cfg(8000000, MSBFIRST, SPI_MODE3); 

extern SPIClass spi;
extern SPISettings spi_cfg;

// chip select pins
#define CS_ACC PE2
#define CS_GYR PE3
//#define CS_BAR PE4 // DOESN'T WORK (PE4 not defined in variants.h)

// LSM303D registers
#define OUT_X_L_M   0x08
#define OUT_X_H_M   0x09
#define OUT_Y_L_M   0x0A
#define OUT_Y_H_M   0x0B
#define OUT_Z_L_M   0x0C
#define OUT_Z_H_M   0x0D
#define CTRL0       0x1F
#define CTRL1       0x20
#define CTRL2       0x21
#define CTRL3       0x22
#define CTRL4       0x23
#define CTRL5       0x24
#define CTRL6       0x25
#define CTRL7       0x26
#define OUT_X_L_A   0x28
#define OUT_X_H_A   0x29
#define OUT_Y_L_A   0x2A
#define OUT_Y_H_A   0x2B
#define OUT_Z_L_A   0x2C
#define OUT_Z_H_A   0x2D
#define OUT_L_TEMP  0x05
#define OUT_H_TEMP  0x06

// L3GD20H registers
#define OUT_X_L_G   0x28
#define OUT_X_H_G   0x29
#define OUT_Y_L_G   0x2A
#define OUT_Y_H_G   0x2B
#define OUT_Z_L_G   0x2C
#define OUT_Z_H_G   0x2D
#define CTRL1_G       0x20
#define CTRL2_G       0x21
#define CTRL3_G       0x22
#define CTRL4_G       0x23
#define CTRL5_G       0x24
#define LOW_ODR     0x39
#define IG_THS_XH 0x32
#define IG_THS_XL 0x33
#define IG_THS_YH 0x34
#define IG_THS_YL 0x35
#define IG_THS_ZH 0x36
#define IG_THS_ZL 0x37
#define IG_SRC 0x31
#define IG_DURATION 0x38

void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
 
  while(!Serial);
  
  Serial1.begin(9600); // gps
  Serial3.begin(57600); // jetson
  Serial2.begin(9600); // header left
  Serial7.begin(9600); // header right
  pinMode(PE9, OUTPUT);
  pinMode(CS_ACC, OUTPUT);
  pinMode(CS_GYR, OUTPUT);
  //pinMode(CS_BAR, OUTPUT);
  digitalWrite(CS_ACC, HIGH);
  digitalWrite(CS_GYR, HIGH);
  //digitalWrite(CS_BAR, HIGH);

  spi.begin();
  writeReg(CS_ACC, CTRL0, 0b10000000); // 1=reboot 0=fifo_en 0=fth_en 00=unused 0=hp_click 0=hpis1 0=hpis2
  delayMicroseconds(1000);
  writeReg(CS_ACC, CTRL1, 0b01100111); // 0110=100hz 0=BDU 1=enable Z 1=enable Y 1=enable X
  writeReg(CS_ACC, CTRL2, 0b00010000); // 00=773hz filter bw 010=6g scale 0=unused 0=AST 0=4wire mode
  writeReg(CS_ACC, CTRL3, 0x00000000);
  writeReg(CS_ACC, CTRL4, 0x00000000);
  writeReg(CS_ACC, CTRL5, 0x11110100); // 1=temp sensor enable 11=mag high res 101=50hz 0=LIR2 0=LIR2
  writeReg(CS_ACC, CTRL6, 0x00000000);
  writeReg(CS_ACC, CTRL7, 0b00000000); // 00=APHM normal 0=bypass filter 0=T_ONLY 0=unused 0=MLP 00=MD1
  
  writeReg(CS_GYR, LOW_ODR, 0x00001000); // software reset
  delayMicroseconds(1000);
  writeReg(CS_GYR, CTRL5_G, 0x10000000); // reboot
  delayMicroseconds(1000);
  writeReg(CS_GYR, CTRL2_G, 0x00000000);
  writeReg(CS_GYR, CTRL3_G, 0x00000000);
  writeReg(CS_GYR, CTRL4_G, 0x00000000); // 245 dps
  writeReg(CS_GYR, CTRL5_G, 0x00000000);
  writeReg(CS_GYR, CTRL1_G, 0x00001111);
}

int8_t readData   = 0x80;
int8_t writeData  = 0x00;

uint8_t readReg(uint8_t CS, uint8_t address) {
  int8_t buffer = 0;
  digitalWrite(CS, LOW);
  delayMicroseconds(100);
  spi.beginTransaction(spi_cfg);
  spi.transfer(readData | address);
  buffer = spi.transfer(writeData);
  spi.endTransaction();
  digitalWrite(CS, HIGH);
  return(buffer);  
}

void writeReg(uint8_t CS, uint8_t address, uint8_t val) {
  digitalWrite(CS, LOW);
  delayMicroseconds(100);
  spi.beginTransaction(spi_cfg);
  spi.transfer(writeData | address);
  spi.transfer(val);
  spi.endTransaction();
  digitalWrite(CS, HIGH);
}

bool ledState = false;
void loop() {
  // put your main code here, to run repeatedly:
  ledState = !ledState;
  digitalWrite(PE9, ledState);
  
  int16_t ax, ay, az;
  int16_t mx, my, mz;
  int16_t gx, gy, gz;
  int16_t temp;
  
  temp = (int16_t)readReg(CS_ACC, OUT_H_TEMP) << 8 | (uint8_t)readReg(CS_ACC, OUT_L_TEMP);
  
  mx = (int16_t) readReg(CS_ACC, OUT_X_H_M) <<8 | (uint8_t)readReg(CS_ACC, OUT_X_L_M);
  my = (int16_t) readReg(CS_ACC, OUT_Y_H_M) <<8 | (uint8_t)readReg(CS_ACC, OUT_Y_L_M);
  mz = (int16_t) readReg(CS_ACC, OUT_Z_H_M) <<8 | (uint8_t)readReg(CS_ACC, OUT_Z_L_M);

  ax = (int16_t)readReg(CS_ACC, OUT_X_H_A) <<8 | (uint8_t)readReg(CS_ACC, OUT_X_L_A);
  ay = (int16_t)readReg(CS_ACC, OUT_Y_H_A) <<8 | (uint8_t)readReg(CS_ACC, OUT_Y_L_A);
  az = (int16_t)readReg(CS_ACC, OUT_Z_H_A) <<8 | (uint8_t)readReg(CS_ACC, OUT_Z_L_A);
  
  gx = (int16_t)readReg(CS_GYR, OUT_X_H_G) << 8 | (uint8_t)readReg(CS_GYR, OUT_X_L_G);
  gy = (int16_t)readReg(CS_GYR, OUT_Y_H_G) << 8 | (uint8_t)readReg(CS_GYR, OUT_Y_L_G);
  gz = (int16_t)readReg(CS_GYR, OUT_Z_H_G) << 8 | (uint8_t)readReg(CS_GYR, OUT_Z_L_G);
  
  Serial3.print("T"); Serial3.print("\t");
  Serial3.print(temp); Serial3.print("\t");
  Serial3.println();

  Serial3.print("M"); Serial3.print("\t");
  Serial3.print(mx); Serial3.print("\t");
  Serial3.print(my); Serial3.print("\t");
  Serial3.print(mz); Serial3.print("\t");
  
  Serial3.println();
  
  Serial3.print("A"); Serial3.print("\t");
  Serial3.print(ax); Serial3.print("\t");
  Serial3.print(ay); Serial3.print("\t");
  Serial3.print(az); Serial3.print("\t");

  Serial3.println();
  
  Serial3.print("G"); Serial3.print("\t");
  Serial3.print(gx); Serial3.print("\t");
  Serial3.print(gy); Serial3.print("\t");
  Serial3.print(gz); Serial3.print("\t");
  
  Serial3.println();
  Serial3.flush();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants