element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
RoadTests & Reviews
  • Products
  • More
RoadTests & Reviews
Blog MSP430FR4133 Launchpad - Magnetic North Visualisation
  • Blog
  • RoadTest Forum
  • Documents
  • RoadTests
  • Reviews
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join RoadTests & Reviews to participate - click to join for free!
  • Share
  • More
  • Cancel
  • Author Author: tomaja
  • Date Created: 26 Nov 2015 9:43 AM Date Created
  • Views 1115 views
  • Likes 5 likes
  • Comments 5 comments
Related
Recommended
  • msp430fr4133
  • ccs
  • illuminated_multirotor
  • texas_insturments
  • lighting
  • ledroadtestplus
  • energia
  • launchpad
  • code_composer_studio

MSP430FR4133 Launchpad - Magnetic North Visualisation

tomaja
tomaja
26 Nov 2015

Related posts:

Kit unboxing - LED RoadTest

Introduction to Bluetooth Low Energy Light Development Kit - CC2540TDK-LIGHT

Android Support for TI's BLE LED Control

MSP430FR4133 Launchpad - Magnetic North Visualisation

Illuminated Tricopter Upgrade - Adding an Addressable LED Ring

MSP430FR4133 BoosterPack for Illuminated Tricopter

Bookshelf Lights Using TI's CC2450 BLE LED Modules

MSP430FR4133 Launchpad with Custom BoosterPack in Action

MSP430FR4133 Launchpad with Custom BoosterPack in Action - appendix

MSP430FR4133 Launchpad with Custom BoosterPack update

Adding Remotely Controlled Headlights to Tricopter

 

 

Development Tools

In my previous post I mentioned that some progress with MSP430FR4133 Launchpad was made, specifically, I managed to read out the magnetometer sensor output, calculate the heading value and display it on the built-in LCD. It wasn't completely straight-forward to do this but after a little bit of research I managed to complete this part of my project.

 

Initial plan was to use Code Composer Studio (CCS) and DriverLib on a Linux Virtual Machine (I'm running it on a OSX host) so I prepared the virtual machine and connected the Launchpad. To be able to connect the Launchpad I had to set up a USB filter in Virtual Box (to pass through the USB device to guest OS) and I think this is where I made a mistake. I only made a specific filter for Launchpad as it was presented on first plug-in. I created a minimal project and hit debug. CSS reported that I need to update the ezFET on my Launchpad so I chose "Upgrade" image I suggest not to run this upgrade from a virtual machine!

 

I'm not sure, but it looks like that during the upgrade procedure VID:PID values were also changed (at least temporarily) and my USB filter was valid only through the first part of upgrade - so it failed. Launchpad become inaccessible from CCS so I was unable to continue using it with CCS. However, there was a workaround that I used for some time until I reached the final solution, I used CSS to build the hex file and then I used mspdebug with tilib driver to flash it (tilib still worked). This also enabled debug but it's much more inconvenient than using CSS for debug.

 

element14 hosts the TI Launchpads section of site (I discovered that recently) with a lot of useful info including example projects. For this LaunchPad Development Kit for MSP430FR4133 Mixed-Signal Microcontroller, this is where I found the OutOfTheBox (msp-exp430fr4133 software examples (.zip) ) example that shows how to use the built-in LCD. I tried to modify this example and use the I2C helpers from DriverLib but I finally gave up and switched to Energia as it's much faster to prototype. Using DriverLib wasn't so trivial since I'm not really proficient with MSP430, I was unable to find the correct order of calls for I2C master read to work.

If anyone knows how to read this magnetometer using DriverLib, please do share that, I would really like to see how it should be done properly.

 

My Launchpad was finally upgraded with success when I found out that there's a beta version of CCS for OSX. When I tried to debug a demo project with this CCS version I was asked to upgrade ezFET again and this time the upgrade process finished properly since there was no VM in the way. CCS was now able to flash the MCU and it was even stopping at breakpoints as it should but I switched to Energia anyway...

 

Energia sketch

For LCD control I used the LCD_Launchpad library and for WS2812b LED strip I found the WS2811Driver library very useful.

 

WS2811Driver didn't work out of the box because Energia boards.txt was set to use 8MHz for this Launchpad. I changed F_CPU setting to 16MHz and that was it - LED strip became fully functional. Seems like this broke the Serial interface but I can live with that - especially since I have a working LCD for debug output.

Internally, WS2811Driver library uses assembly code to manage the strict timing required by WS2812Bs and it relies on the fact that single clock cycle takes 62.5ns to execute.

If you are interested in exact timings please check the WS2812B datasheet (http://www.seeedstudio.com/document/pdf/WS2812B%20Datasheet.pdf)

 

I didn't use external library for the HMC5883L magnetometer, it was simple enough to just use Wire object.

My calculations for heading value are good as long as magnetometer is positioned horizontally, I'm OK with that.

 

So, my Energia sketch looks like this at the moment.

#include <ws2811.h>
#include <WS2811Driver.h>
#include "Wire.h"
#include <stdarg.h>
#include "LCD_Launchpad.h"


// Variables
LCD_LAUNCHPAD myLCD;
WS2811Driver ledStrip;
uint8_t leds[180] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
uint16_t unHeading;
bool bBatteryLow = false;
bool bLeft = false;


void SetupMagnetometer()
{
  Wire.beginTransmission(0x1E);
  Wire.write(0x00);
  Wire.write(0x70);
  Wire.endTransmission();

  Wire.beginTransmission(0x1E);
  Wire.write(0x01);
  Wire.write(0xA0);
  Wire.endTransmission();

  Wire.beginTransmission(0x1E);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission();
}
void ReadMagnetometer()
{
  // Request 6 bytes
  Wire.requestFrom(0x1E, 6);
  int value = 0;
  bool secondByte = false;
  int currentAxis = 0;
  float x, y, z;

  // Read 6 bytes
  while(Wire.available())
  {
    char c = Wire.read();
    if(!secondByte)
    {
      value = int(c) << 8;
      secondByte = true;
    }
    else
    {
      secondByte = false;
      value |= c;
      if(currentAxis == 0)
      {
        Serial.print("x: ");
        x = value;
        Serial.print(x);
      }
      else if(currentAxis == 1)
      {
        Serial.print("    y: ");
        y = value;
        Serial.print(y);
      }
      else
      {
        Serial.print(    "z: ");
        z = value;
        Serial.print(z);
      }
      // Serial.print(value);
      Serial.println("  ");
      currentAxis++;
    }

  }
  Wire.endTransmission();
  float heading = 0.0;

  // Calculate heading from magnetic field vector
  // This could be more compact but I found it easier to read
  // when 4 quadrants are processed separately
  if(x > 0 && z > 0)
  {
    heading = atan(z / x) * 180.0 / 3.141529;
  }
  else if (x < 0 && z > 0)
  {
    heading = 180 + atan(z / x) * 180.0 / 3.141529;
  }
  else if (x < 0 && z < 0)
  {
    heading = 180 + atan(z / x) * 180.0 / 3.141529;
  }
  else if(x > 0 && z < 0)
  {
    heading = 360 + atan(z / x) * 180.0 / 3.141529;
  }
  else if(x == 0)
  {
    if(z > 0)
    {
      heading = 90.0;
    }
    else
    {
      heading = 270.0;
    }
  }
  else if(z == 0 && x < 0)
  {
    heading = 180.0;
  }
  unHeading = heading;

  // Prepare for next sensor read cycle
  Wire.beginTransmission(0x1E);
  Wire.write(0x03);
  Wire.endTransmission();
}
void UpdateStrip()
{
  // Show magmetometer reading
  int led = unHeading / 6;
  leds[led * 3] = (char)0xFF;
  leds[led * 3 + 1] = (char)0xFF;
  leds[led * 3 + 2] = (char)0xFF;

  // Battery low
  if(bBatteryLow)
  {
    int i = 0;
    for(; i < sizeof(leds) / 3; i++)
    {
      leds[i * 3 + 1] = 0x33;
    }
  }

  // Controls
  if(bLeft)
  {
    int i = 0;
    int nOffset = 25;
    for(; i < sizeof(leds) / 36; i++)
    {
      leds[(i + nOffset) * 3] = 30 / abs(i - 2.5);
    }
  }

  // Temporarily disable interrupts to make sure writing to LED strip is not interrupted
  noInterrupts();
  ledStrip.write(leds, sizeof(leds));
  interrupts();

  memset(leds, 0, sizeof(leds));
}
void UpdateLCD()
{
  myLCD.clear();
  myLCD.println(unHeading);
}
void CheckBattery()
{
  if((unHeading < 60 && unHeading > 20) || (unHeading > 80 && unHeading < 200))
  {
    bBatteryLow = true;
  }
  else
  {
    bBatteryLow = false;
  }
}
void CheckCommands()
{
  if(unHeading > 80 && unHeading < 200)
  {
    bLeft = true;
  }
  else
  {
    bLeft = false;
  }
}
void setup()
{
  Serial.begin(9600);

  Wire.begin();
  SetupMagnetometer();
  myLCD.init();

  ledStrip.setLEDCount(60);
  ledStrip.begin();
}
void loop()
{
  ReadMagnetometer();
  CheckBattery();
  CheckCommands();
  UpdateStrip();
  UpdateLCD();
  delay(10);
}
         

 

If you check the code you will notice that I plan to add more features so I'm turning some LEDs on depending on the heading value as a test but later I will use the real inputs like:

  • Low battery warning (all WS2812B modules turn the red LED on)
  • Transmitter stick positions (green LED turn one on the corresponding tricopter side when pitch and roll sticks are moved away from middle position)

 

Demonstration

And finally, here's the fun part - video demonstration of my LED compass:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

Thanks for going through my project log!

 

Dragan

  • Sign in to reply

Top Comments

  • DAB
    DAB over 9 years ago +1
    Nice Post. DAB
  • jw0752
    jw0752 over 9 years ago +1
    Hi Dragan, I appreciated the inclusion of the difficulties in getting to the final results. To me these are always the most interesting part of the process and make the final demo a real accomplishment…
  • fvan
    fvan over 9 years ago +1
    Great stuff Dragan!
  • tomaja
    tomaja over 9 years ago in reply to fvan

    Thanks, Frederick!

    I will soon mount everything on my tricopter and give it a go, I expect that will look good in the air...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fvan
    fvan over 9 years ago

    Great stuff Dragan!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • jw0752
    jw0752 over 9 years ago

    Hi Dragan,

    I appreciated the inclusion of the difficulties in getting to the final results. To me these are always the most interesting part of the process and make the final demo a real accomplishment.

    John

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • tomaja
    tomaja over 9 years ago in reply to DAB

    Thanks DAB! I really enjoy working on this project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 9 years ago

    Nice Post.

     

    DAB

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube