Razor Monologue by Omar Lim

Posted by Mohammed 18/10/2016 0 Comment(s) Microcontrollers,
 This tutorial is a courtresy of Omar Lim. Thank you for your help and support.

Intro

arduino-communicate-razor-9dof

In this article, I will try to explain how to communicate with the 9DOF Razor IMU using various Arduino boards. I assume that you have a basic understanding of IMUs and have been acquainted with the 9DOF Razor IMU

I got my 9DOF Razor IMU from Zero Ohm Electronics, A company here in Dubai that sell electronics parts. They import items from sparksfun, adafruit, and Arduino, and making these available in Dubai. The supporting hardware (FTDI Basic, Arduino Pro Mini, breadboards, and wire jumpers) are from them as well.

 

Communicating with the 9DOF Razor IMU (from henceforth will be referred to as RazorIMU), proved to be a challenge. The original design of the board, is to communicate using the RX/TX pin of the built-in atmega328. This mode of communication is the supposed cheapest and assumed simplest of all the protocols that can be used. It is indeed straight forward, which use very minimal hardware, and if connecting the RazorIMU to a computer is your final project, then it is the simplest connection there is.

What if we want to control a servo motor using the values provided by the IMU (Yeah, RazorIMU is still to long, now I'll just call it 'the IMU' and I'll be referring to the 9DOF Razor IMU, not IMUs in general). A good example is the camera gimbal and other stabilization platforms.

Let's get started

Requirement:

Step 0: Configuring the Razor

For some reason I've decided to edit my previous article about the IMU, then my browser decided to clear the contents, then auto saved, and then crash (no I did not accidentally clicked the delete button and subsequently clicked OK instead of cancel).
 
Long story short, I'll put the IMU's reprogramming here.
> > > > NOTE: The 9DOF Razor IMU uses 3.3V. < < < <
  • Connect the 9DOF Razor IMU to the computer using the FTDI Basic board
9dof-razor-imu
  • Download (there a Download ZIP in the lower right side) the 9DOF Razor IMU Firmware here
  • Extract and copy the folder Razor_AHRS (inside arduino folder) to your computer's Arduino folder (probably inside your documents eg: "C:\Users\alipin\Documents\Arduino" )
  • Open Arduino IDE, click File►Sketchbook►Razor_AHRS
  • Look for the User Setup Area
/*****************************************************************/
/*********** USER SETUP AREA! Set your options here! *************/
/*****************************************************************/
  • Uncomment (remove the forward slashes of) the board you are using, in this case the SEN-10736
// HARDWARE OPTIONS
/*****************************************************************/
// Select your hardware here by uncommenting one line!
//#define HW__VERSION_CODE 10125 // SparkFun "9DOF Razor IMU" version "SEN-10125" (HMC5843 magnetometer)
#define HW__VERSION_CODE 10736 // SparkFun "9DOF Razor IMU" version "SEN-10736" (HMC5883L magnetometer)
//#define HW__VERSION_CODE 10183 // SparkFun "9DOF Sensor Stick" version "SEN-10183" (HMC5843 magnetometer)
//#define HW__VERSION_CODE 10321 // SparkFun "9DOF Sensor Stick" version "SEN-10321" (HMC5843 magnetometer)
//#define HW__VERSION_CODE 10724 // SparkFun "9DOF Sensor Stick" version "SEN-10724" (HMC5883L magnetometer)
  • Set the baudrate to 19200 (any higher and SoftwareSerial will give out garbarge)
// OUTPUT OPTIONS
/*****************************************************************/
// Set your serial port baud rate used to send out data here!
#define OUTPUT__BAUD_RATE 19200
  • For sending binary outputs, 20ms is enough
// Sensor data output interval in milliseconds
// This may not work, if faster than 20ms (=50Hz)
// Code is tuned for 20ms, so better leave it like that
#define OUTPUT__DATA_INTERVAL 20  // in milliseconds
 
Here's a table for reference:
 
BAUDMillis
No DataBINTXT
57600121315
38400131315
28800 
19200131723
14400 
9600183145
  • Set the output_format to binary OUTPUT__FORMAT_BINARY
// Select your startup output mode and format here!
int output_mode = OUTPUT__MODE_ANGLES;
int output_format = OUTPUT__FORMAT_BINARY;
  • In the future, a steady stream of data may be needed. It can be set here. But for now, make it false
// Select if serial continuous streaming output is enabled per default on startup.
#define OUTPUT__STARTUP_STREAM_ON false  // true or false
  • Tada! Its ready to upload. Set the board to Arduino Pro or Promini 3.3V, select the correct COM port then click Upload.
  • Disconnect the 9DOF Razor IMU and prepare for the next step.
 

Step 1: Arduino Connection

Connect like this:
  • TX to Pin 2 (level shifter is necessary if 5V Arduino)
  • RX to pin 3 (level shifter is necessary if 5V Arduino)
  • 3.3V to 3V3
  • GND to GND
> > > > NOTE: The 9DOF Razor IMU uses 3.3V. < < < <
 

Arduino UNO

Arduino Uno's vorking voltage 5V, which means that the RX/TX lines will be working at 5V. The 9DOF Razor IMU works at 3.3 voltage level. To make this work, a level shifter should be connected between the two boards. Or at the very least, a voltage divider between the transmit line of the UNO and the RX line of the IMU.
arduino-uno-with-level-shifter-board
Arduino Uno with level shifter board from sparksfun
arduino-uno-with-voltage-divider-to-imu-rxline
Arduino UNO with voltage divider to IMU's RX line (10k left, 20k right)

Arduino Pro Mini (3.3v)

The Arduino Pro Mini (3.3V), like the name suggests, works with 3.3 volt (not to be confused with Arduino Pro Mini 5v, which again, as the name suggest, works with 5 volts) Using this board, a direct connection between the IMU and the Pro Mini is possible. Please note that the FTDI Basic board used is also 3.3v
 
arduino-pro-min
Arduino Pro Mini (3.3V) can connect directly to the IMU, but FTDI Basic 3.3V is needed.
 
Connect the Arduino to your computer, if no smoke is produced, we can proceed.
 

Step 2:

The main problem of these boards (UNO and Pro Mini) is that they only have 1 Serial Port. There's a way to connect two serial devices to a single hardware serial but it involves more complicated circuit and programming (I'll discuss it some other time). I used the SoftwareSerial Library that comes with the ArduinoIDE.

Here's the code:

/*
 ------------------------------------
 9DOF Razor IMU SoftwareSerial Reader
 ------------------------------------
 
 Reads IMU data from 9DOF Razor IMU via software serial.
 
 Circuit:
 The 9DOF Razor IMU work on 3.3v, check your board's
 voltage levels before proceeding

 | ARDUINO Pro Mini  |  9DOF Razor IMU  |
 |--------------------------------------|
 |    PIN 2          |        TX        |
 |    PIN 3          |        RX        |
 |--------------------------------------| 
 
 Check other connection methods here:
       http://alihpin.blogspot.ae/2015/02/the-razor-monologue.html
 
 
 */

#include <SoftwareSerial.h>
SoftwareSerial softSerial(2, 3);
String buff;



void setup() {
  Serial.begin(115200);
  softSerial.begin(19200);
}

void loop() {
  if(softSerial.available()){
    buff = "";
    while(softSerial.available()){
      char in = (char)softSerial.read();
      buff += in;
    }
    Serial.println(buff);
    parseData(buff);
  }

  if(Serial.available()){
    while(Serial.available()){
      softSerial.write(Serial.read());
    }
  }
}

void parseData(String s){
  
  union byte2float{
  byte bval[4];
  float fval;
}
b2f;
  
  float yaw;
  float pitch;
  float roll;
  int i=0;
  String temp;
  //Check if ASCII or Binary (usually, binary output doesn't start with #)
  if(s.substring(0,1)=="#"){
    if(s.substring(1,4)=="YPR"){
      Serial.println("Output is Text");
      Serial.println(s.substring(5,s.indexOf(",",i)));
      yaw = s.substring(5,s.indexOf(",",i)).toFloat();

      i = 1 + s.indexOf(",",i) ;
      Serial.println(s.substring(i,s.indexOf(",",i)));
      pitch = s.substring(i,s.indexOf(",",i)).toFloat();

      i = 1 + s.indexOf(",",i);
      Serial.println(s.substring(i,s.indexOf(",",i)));
      roll = s.substring(i,s.indexOf(",",i)).toFloat();


    }
  }
  else{
    // 1234 5678 9101112
    Serial.println("Output is Binary: ");
    byte b[13];
    s.getBytes(b,13);
    Serial.println("[#]\t[A]\t[B]\t[Ah]\t[Bh]");
    for(int x=0;x<12;x++){
      Serial.print("[");
      Serial.print(x,DEC);
      Serial.print("]\t");
      Serial.print(s[x]);
      Serial.print("\t");
      Serial.print((char)b[x]);
      Serial.print("\t");
      Serial.print((byte)s[x],HEX);
      Serial.print("\t");
      Serial.println((byte)b[x],HEX);
    }
    b2f.bval[0] = b[0];
    b2f.bval[1] = b[1];
    b2f.bval[2] = b[2];
    b2f.bval[3] = b[3];
    yaw = b2f.fval;    
    b2f.bval[0] = b[4];
    b2f.bval[1] = b[5];
    b2f.bval[2] = b[6];
    b2f.bval[3] = b[7];
    pitch = b2f.fval;    
    b2f.bval[0] = b[8];
    b2f.bval[1] = b[9];
    b2f.bval[2] = b[10];
    b2f.bval[3] = b[11];
    roll = b2f.fval;    
  }
  Serial.print("Yaw: ");
  Serial.println(yaw);
  Serial.print("Pitch: ");
  Serial.println(pitch);
  Serial.print("Roll: ");
  Serial.println(roll);
}
 

The code could be optimized further, but it's easier to visualize it this way.

  • Create a new file and paste the code
  • Select the board and Serial port to be used
  • Click Upload

Step 3: Testing

  • While IMU is connected to the Arduino board, and the Arduino board is connected to the computer, open the serial monitor.
  • Type #f and press enter
  • There should be a reply parsing the values from the IMU

Troubleshooting

avrdude: stk500_getsync(): not in sync: resp=0x00
  • The board selected in not correct
    • For 9DOF Razor IMU Programming select Arduino Pro or Pro Mini 3.3v with ATmega328
  • The serial port is not correct
    1. Remove all Arduinos and USB Serial Connected to the computer
    2. Run "devmgmt.msc" ([WIN Key] + R)
    3. Check under Ports (COM & LPT)
    4. Connect the Arduino (or the FTDI Basic if programming the IMU)
    5. Check the Ports (COM & LPT) again, and whatever COM port shows up, use that.
  • You burned the board
    • Order a new one.
    • Buy the correct 3.3V FTDI Basic board
That's it! Enjoy!
 
This article is a courtesy of
Author: Omar Lim
Blog: https://alihpin.blogspot.ae/
 Hands down for helping the society and community .

Leave a Comment