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 & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • 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
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • 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
Get Closer Wearables Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Get Closer Wearables Design Challenge
  • More
  • Cancel
Get Closer Wearables Design Challenge
Blog "Get Closer Challenge"  - Navigation Glove
  • Blog
  • Forum
  • Documents
  • Files
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Former Member
  • Date Created: 27 Aug 2013 6:44 AM Date Created
  • Views 620 views
  • Likes 0 likes
  • Comments 3 comments
  • flora
  • Wearables
  • adafruit
  • arduino
  • get_closer
Related
Recommended

"Get Closer Challenge"  - Navigation Glove

Former Member
Former Member
27 Aug 2013

I'm sorry that it's been a long time since my last post - sorry about that. Let's get to good stuff!

 

After testing the parts and proving that they work, I felt compelled to see how hard it would be to make a compass out of them. Testing a little further, I find that the FLORA Accelerometer/Compass to be a little mixed, performance-wise. At low velocity (so that the only acceleration is due to gravity) the magnitude of the acceleration vector is right around 1000. I had initially assumed that the compass would be similarly well-calibrated but I find that the range of values would be far less regular (I think that my x-axis reports values that are always negative). Below is a bit of code I used to figure out the range of values for my magnetometer.

 

#include <Wire.h>

#include <Adafruit_LSM303.h>

 

Adafruit_LSM303 lsm;

 

long x;

long y;

long z;

long minX = 1000;

long maxX = 0;

long minY = 1000;

long maxY = 0;

long minZ = 1000;

long maxZ = 0;

 

void setup(){

  Serial.begin(9600);

 

  if (!lsm.begin()){

    Serial.println("Oops ... unable to initialize the LSM303. Check your wiring!");

    while (1);

  }

}//end of setup

 

void loop(){

  lsm.read();

 

  /*X*/

  x = lsm.magData.x;

  Serial.print(x);

  Serial.print("\t");

  if(x>maxX) maxX = x;

  if(x<minX) minX = x;

  Serial.print(minX);

  Serial.print("\t");

  Serial.print(maxX);

  Serial.print("\t");

 

  /*Y*/

  y = lsm.magData.y;

  Serial.print(y);

  Serial.print("\t");

  if(y>maxY) maxY = y;

  if(y<minY) minY = y;

  Serial.print(minY);

  Serial.print("\t");

  Serial.print(maxY);

  Serial.print("\t");

 

  /*Z*/

  z = lsm.magData.z;

  Serial.print(z);

  Serial.print("\t");

  if(z>maxZ) maxZ = z;

  if(z<minZ) minZ = z;

  Serial.print(minZ);

  Serial.print("\t");

  Serial.print(maxZ);

  Serial.print("\t");

 

  Serial.println();

}

 

I would load that code and then orient the sensor in all different directions and then observe my minimum and maximum values in each axis. I am not sure why the compass would be so much less well-calibrated from the manufacturer than the accelerometer - could they have been damaged by the magnet shipped in the package? On a somewhat embarrassing note, my initial attempts at running the calibration code during my lunch break were thwarted by my metal desk which has a number of (small) magnets stuck to the side. These calibration values would then be used to make a much more functional compass. If you are trying this at home, please make sure to generate your own calibration data - if you try to use mine let's just say that "your mileage may vary".

 

#include <Wire.h>

#include <Adafruit_LSM303.h>

#include <Adafruit_NeoPixel.h>

 

const int leds = 16;//number of NeoPixels

const int onTIme = 8000;//time to keep the LEDs on

 

float bearing = 0;//for now we will point north

unsigned long upTime=0;

 

//Adafruit objects

Adafruit_LSM303 lsm;

Adafruit_NeoPixel ring = Adafruit_NeoPixel(leds, 6, NEO_GRB + NEO_KHZ800);

 

//a little vector type

typedef struct vect_s{

    float x;

    float y;

    float z;

} vect;

 

 

void setup(){

  Serial.begin(9600);

 

  // Try to initialise and warn if we couldn't detect the chip

  if (!lsm.begin()){

    Serial.println("Oops ... unable to initialize the LSM303. Check your wiring!");

    while (1);

  }//end of if

 

  ring.begin();

  ring.show();  //initialize the pixels to off

}//end of setup

 

 

void loop(){

  lsm.read();

 

  if(isAwake()){

    upTime = millis()+onTime;

  }//end of isAwake

 

  if(millis()<upTime){

    //check level and buffer the led display

    if(isLevel()){

      //calculate our bearing

      float o = calc();

      int d = map(o-bearing,0,360,0,16);

      Serial.println(d);

      black();

      ring.setPixelColor(d,ring.Color(0,100,0));//set the LED closest to the bearing on

    }//end of if

    else{

      red();//all the LEDs turn red

    }//end of else

  }//end of if

  else{

    black();

  }//end of else

 

  //refresh the LED ring

  ring.show();

 

}//end of loop

 

 

//function to wake up

boolean isAwake(){

  float acc = lsm.accelData.x*lsm.accelData.x + lsm.accelData.y*lsm.accelData.y + lsm.accelData.z*lsm.accelData.z;

  acc = sqrt(acc);

  Serial.println(acc);

  return(acc>2000);//2000 is an arbitrary, experimentally-determined number

}//end of isAwake

 

 

//function to calculate orientation

float calc(){

  float orient;

  vect east;//a vector that will point east

  //need to calibrate the magnetometer!

  //-1289 -60

  //-1576 -40

  //-800 160

  float magX = map(lsm.magData.x,-1289,-60,-1000,1000);

  float magY = map(lsm.magData.y,-1576,-40,-1000,1000);

  float magZ = map(lsm.magData.z,-800,160,-1000,1000);

  //cross multiplication: (gravity) x (magnetic north) = (east)

  east.x = lsm.accelData.y*magZ-lsm.accelData.z*magY;

  east.y = lsm.accelData.z*magX-lsm.accelData.x*magZ;

  east.z = lsm.accelData.x*magY-lsm.accelData.y*magX;

  //determine our orientation relative to magnetic morth, in degrees (clockwise)

  orient = atan2(east.x,-east.y);

  orient = orient*180/PI+180;

  //print the results

  Serial.print("X: "); Serial.print(east.x);     Serial.print(" ");

  Serial.print("Y: "); Serial.print(east.y);         Serial.print(" ");

  Serial.print("Z: "); Serial.print(east.z);       Serial.print(" ");

  Serial.print("O: "); Serial.println(orient);       Serial.print(" ");

  return orient;

}//end of bear

 

 

//function to determine how level the accelerometer (and my palm) is

boolean isLevel(){

  float xy = sqrt((lsm.accelData.x*lsm.accelData.x)+(lsm.accelData.y*lsm.accelData.y));

  float tilt = atan(xy/lsm.accelData.z);

  tilt = tilt*180/PI;

  boolean isLevel = (tilt<30);//check to see if the tilt is less than 30 degrees

  return isLevel;

}//end of level

 

 

//function to turn all LEDs off

void black(){

  for(int i=0;i<leds;i++){

    ring.setPixelColor(i,ring.Color(0,0,0));

  }//end of for loop

}//end of black

 

 

//function to turn all LEDs red

void red(){

  for(int i=0;i<leds;i++){

    ring.setPixelColor(i,ring.Color(50,0,0));

  }//end of for

}//end of red

 

And I went ahead and added a wake-on-shake function. I am trying to code in a modular fashion so that I can recycle large amounts of it later. Oh, I picked up one of Adafruit's new NeoPixel Rings to make a nice, clean prototype display (or so I could procrastinate the sewing a little longer). At the moment, the code does not support the palm-down orientation.

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image
[Edit: Forgot to include the video]

You can see here the compass display (green), tilt indication (red), and of course the wake-on-shake function (and going back to sleep).

 

The NeoPixel Ring has 16 LEDs and I think that my glove will only be able to fit about 8 sewable pixels. I think that I will have to upgrade the lighting effects substantially so that the display is smoother and so it can imply an angle between two pixels (by adjusting their intensity).

 

So, where are we at?

  1. Review and test parts - I'll verify that the electronics work and I will run the code from the Adafruit tutorials.
  2. LED Array - I'll take my first shot at sewing with stainless steel and build a circular, 8-NeoPixel array sized to fit in the palm of my hand
  3. Accelerometer - The accelerometer will be used to determine if I am holding my palm up or down AND to signal my LED array to turn on if I shake it hard enough.
  4. Compass - The magnetometer will be used while the LEDs are active to indicate my bearing, compensating for hand orientation
  5. GPS - The GPS unit will be used to help calculate initial bearings and possibly distance as well. I'll have to see how the device reacts to different orientations and fabrics.
  6. Physical Layout - I will have to figure out how to fit all of those goodies on the front and back of a glove (while not sacrificing wearability)
  7. User Experience - This is probably a good time to make the lighting pattern more interesting or informative, iron out bugs, test accuracy and a few failure modes.
  8. Sewing - This will be an interesting experience, I hope that local fabric stores will allow me to test the light diffusion/transmission of different fabrics I will encase the finalized electronics in. I also have never sewn gloves before but look forward to practicing. A lot. I really want to make this look like a real/well-finished product.
  9. Light Balancing? - The Lux sensor might help me adjust the brightness level for appropriate day/nighttime use.
  10. Low Power? - If I have time, I will try to see if there are ways to reduce power consumption.
  11. Capacitive touch buttons? - If I have time, it would be nice to be able to change destinations.

 

I have seen a few examples of bearing calculation and it looks like some of my fellow road testers have started dabbling with it as well. That should come pretty quickly!

 

Sorry for the multiple walls of code text. It may happen again.

 

And yes... ...you will get to see my sewing soon.

  • Sign in to reply
  • zengirl2
    zengirl2 over 12 years ago in reply to Former Member

    So far my stitching has been on heavier synthetic poly/cotton, cotton, and lighter weight stretch poly.  I would definitely opt for the heavier cotton or poly cotton mix -- especially since you want something physically stronger.  I noticed that the stitches don't shift as much on the tighter/cotton weave as well. I guess it would depend on the look of your glove.  I really like the neopixel ring and it should make it really interesting looking.  You may get some steampunk takers!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to bekathwia

    Thanks Becky, I will have to look in to that library. I think that my calibration effort is passable, but we will see if it holds up to the test of time.

     

    Also, does anyone have recommendations for base fabric to stitch FLORA components to? My intuition is to use fabrics with relatively tight weave perhaps in a heavier weight. I'd love some searchable keywords or links!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • bekathwia
    bekathwia over 12 years ago

    Have you tried using the Pololu library for the LSM303? We're always working on our libraries but theirs already has some auto-calibration that might prove useful. We used it in the Citi Bike Helmet project to allow for tilt-compensated headings:

     

    http://learn.adafruit.com/citi-bike-helmet

    • Cancel
    • Vote Up 0 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