Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Memsic 2125 Accelerometer / Servo


  • Please log in to reply
6 replies to this topic

#1 Jason Smith

Jason Smith

    Member

  • Members
  • PipPip
  • 17 posts
  • LocationEnglewood, CO

Posted 14 August 2010 - 07:12 AM

All,

I successfully got the Memsic 2125 Accelerometer to work on my Netduino, so I decided to take a crack at controlling a servo by measuring Tilt. I'm sure I could do a lot to make this more efficient but I just wanted to get this working first:

Below is the code I used (I plan on doing a lot more work to get this going right. Once I do, I will properly comment my code and clean things up to make it more user friendly.):

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Memsic
{
    public class Program
    {
        static int count = 0;
        static uint _lastposition = 0;
        static InputPort Xin = new InputPort(Pins.GPIO_PIN_D2, false, Port.ResistorMode.Disabled);
        static InputPort Yin = new InputPort(Pins.GPIO_PIN_D3, false, Port.ResistorMode.Disabled);
        static PWM ServoY = new PWM(Pins.GPIO_PIN_D9);
        public static void Main()
        {
            while (true)
            {
                int X = TiltToServoPulse(GhettoTilt(Xin));
                int Y = TiltToServoPulse(GhettoTilt(Yin));
                MoveServo(ServoY, (uint)Y);
                //Debug.Print("X:" + X + "," + "Y: " +  Y);
             }
        }

       //Read the specified port and grab some values to calculate Ghetto Tilt.
        static int GhettoTilt(InputPort axe)
        {
            count = 0;
            // Loop until pin reads a low 
            while (axe.Read() == true) { }
            // Loop until pin reads a high 
            while (axe.Read() == false) { }
            // Loop until pin reads a low and count
            while (axe.Read() == true)
            {
                if (axe.Read() == false) { break; }
                count += 1;
            }
            count = count - 21;
            return count;
        }

        static void MoveServo(PWM whatservo, uint whereto, int sleep = 0)
        {
            if (_lastposition == whereto) { return; }
            uint HowLong = 0;
            if (whereto > 2000 || whereto < 1000) { return; }
            whatservo.SetPulse(20000, whereto);
            if (_lastposition == 0) { HowLong = 300; }
            else { HowLong = _lastposition > whereto ? (_lastposition - whereto) / 3 : (whereto - _lastposition) / 3; }
            Debug.Print("" + HowLong);
            Thread.Sleep((int)HowLong);
            whatservo.SetPulse(0, whereto);
            _lastposition = whereto;
            if (sleep != 0) { Thread.Sleep(sleep); }
        }

        static int TiltToServoPulse(double Tilt)
        {
            double pulse = 0;
            Tilt = Tilt - 1;
            double calc1 = Tilt / 18;
            pulse = (calc1 * 1000) + 1000;
            return (int)pulse;
        }
    }
}


..and a video of the results:
http://www.youtube.com/watch?v=xTijhSgqMfM

Jason

#2 greg

greg

    Advanced Member

  • Members
  • PipPipPip
  • 169 posts
  • LocationChicago, IL

Posted 14 August 2010 - 01:18 PM

All,

I successfully got the Memsic 2125 Accelerometer to work on my Netduino, so I decided to take a crack at controlling a servo by measuring Tilt. I'm sure I could do a lot to make this more efficient but I just wanted to get this working first:

Below is the code I used (I plan on doing a lot more work to get this going right. Once I do, I will properly comment my code and clean things up to make it more user friendly.):

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Memsic
{
    public class Program
    {
        static int count = 0;
        static uint _lastposition = 0;
        static InputPort Xin = new InputPort(Pins.GPIO_PIN_D2, false, Port.ResistorMode.Disabled);
        static InputPort Yin = new InputPort(Pins.GPIO_PIN_D3, false, Port.ResistorMode.Disabled);
        static PWM ServoY = new PWM(Pins.GPIO_PIN_D9);
        public static void Main()
        {
            while (true)
            {
                int X = TiltToServoPulse(GhettoTilt(Xin));
                int Y = TiltToServoPulse(GhettoTilt(Yin));
                MoveServo(ServoY, (uint)Y);
                //Debug.Print("X:" + X + "," + "Y: " +  Y);
             }
        }

       //Read the specified port and grab some values to calculate Ghetto Tilt.
        static int GhettoTilt(InputPort axe)
        {
            count = 0;
            // Loop until pin reads a low 
            while (axe.Read() == true) { }
            // Loop until pin reads a high 
            while (axe.Read() == false) { }
            // Loop until pin reads a low and count
            while (axe.Read() == true)
            {
                if (axe.Read() == false) { break; }
                count += 1;
            }
            count = count - 21;
            return count;
        }

        static void MoveServo(PWM whatservo, uint whereto, int sleep = 0)
        {
            if (_lastposition == whereto) { return; }
            uint HowLong = 0;
            if (whereto > 2000 || whereto < 1000) { return; }
            whatservo.SetPulse(20000, whereto);
            if (_lastposition == 0) { HowLong = 300; }
            else { HowLong = _lastposition > whereto ? (_lastposition - whereto) / 3 : (whereto - _lastposition) / 3; }
            Debug.Print("" + HowLong);
            Thread.Sleep((int)HowLong);
            whatservo.SetPulse(0, whereto);
            _lastposition = whereto;
            if (sleep != 0) { Thread.Sleep(sleep); }
        }

        static int TiltToServoPulse(double Tilt)
        {
            double pulse = 0;
            Tilt = Tilt - 1;
            double calc1 = Tilt / 18;
            pulse = (calc1 * 1000) + 1000;
            return (int)pulse;
        }
    }
}


..and a video of the results:
http://www.youtube.com/watch?v=xTijhSgqMfM

Jason


Very nice! Good work!

I can't wait for my netduino to show up sometime next week!

#3 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 14 August 2010 - 02:41 PM

Jason, That's pretty awesome. Once you get it cleaned up, we'd love to showcase this for a while on the Projects page... If you'd be interested in that... We love showing off the cool things that community members build. Chris

#4 Chris Seto

Chris Seto

    Advanced Member

  • Members
  • PipPipPip
  • 405 posts

Posted 14 August 2010 - 05:12 PM

Very nice! Now, just get another servo, a sheet of plywood and make yourself a tilt maze. You could use light sensors to detect where the ball is and include random events to make the game harder, like maybe the axises would swap in the middle of a game.

#5 Jason Smith

Jason Smith

    Member

  • Members
  • PipPip
  • 17 posts
  • LocationEnglewood, CO

Posted 14 August 2010 - 07:20 PM

Jason,

That's pretty awesome. Once you get it cleaned up, we'd love to showcase this for a while on the Projects page... If you'd be interested in that... We love showing off the cool things that community members build.

Chris


Thanks Chris! That sounds great! I will work on getting everything working a bit better this weekend and post my results here in the forum.

Jason.

#6 Jason Smith

Jason Smith

    Member

  • Members
  • PipPip
  • 17 posts
  • LocationEnglewood, CO

Posted 14 August 2010 - 07:22 PM

Very nice!

Now, just get another servo, a sheet of plywood and make yourself a tilt maze. You could use light sensors to detect where the ball is and include random events to make the game harder, like maybe the axises would swap in the middle of a game.


Very true! I think it would actually be pretty simple to do something like this. Would probably be a fun little game.

Jason.

#7 Jim B

Jim B

    New Member

  • Members
  • Pip
  • 6 posts
  • LocationUSA

Posted 31 December 2010 - 03:48 AM

Thanks! I was able to get readings quickly using the snippet you provided. One thing, though... I had to change 21 to 31 in the computation method. This changed my 'at rest' readings to all 0's, and gave pos/neg values when I tilted the accelerometer. Thanks again! Jim B




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.