.Net Gadgeteer: Robot (한국어)

장애물을 피해 움직이는 .Net Gadgeteer (닷 넷 가젯티어)로봇입니다. 며칠후 로봇에 사용된 컴퓨터 코드를 올리도록 하겠습니다. 궁금한 점이 있으시면 메모를 남겨 주세요.  

Update: Source is now available: http://gotoloop.codeplex.com/

Advertisements

.Net Gadgeteer: IR Radar

In this demo I am going to show how to integrate with multiple external (non-Gadgeteer) hardware devices. 

In previous posts I have covered the basics of using a single extender module to connect to devices like a Bluetooth module. Here we show that it is possible to use several extenders. This is what I meant when I said .Net Gadgeteer is “hardware glue” in a previous post.

 

Suppose you wanted to connect a servo and an IR range finder (such as a Sharp GP2Y0A21F9Y)  to make a IR radar gadget. I want the servo to sweep the IR range finder across an arc and measure distance. Then I want the results to be displayed like a radar screen.

The issue you will run into is that there are no sockets that cover both PWM (needed by the servo) and analog input (needed by the IR range finder). This is a case where you must use multiple Extender Modules.

You could create your own extender module too. Just use the Extender Module that comes with the GHI kit have to map the pins with a voltmeter.

In this example, I opted to get another Extender Module. Here is what it looks like. Notice that the new one is using a straight header I soldered on. The other one uses a 90 degree header. This gives me more options later when prototyping. 

The code is very simple (works but could be improved):

   public partial class Program
    {
         void ProgramStarted()
        {
            // Do one-time tasks here
            Debug.Print("Program Started");
            GT.Interfaces.PWMOutput servo = this.extender.SetupPWMOutput(GT.Socket.Pin.Seven);//must be 7,8,9
            GT.Interfaces.AnalogInput IRRange = this.extender1.SetupAnalogInput(GT.Socket.Pin.Four);
            IRRange.Active = true;
            servo.Active = true;
            ushort minDistance = 0;
            ushort minDistanceTemp = 0;
            uint period = 20 * 1000 * 1000;
            uint hightime = 2000; //hightime range 700-2000 *1000
            uint minHightime = 0;
            int t = 0;
            int x0 = (int)(display.Width / 2);
            int y0 = (int)display.Height - 50;
            int x1 = 0;
            int y1 = 0;
            int factor;
            const int ANGLE_STEP_SIZE = 10;
            int diameter = 1500;
            int angle = 270;
            display.SimpleGraphics.SetPixel(GT.Color.White, 1, 1);
            servo.SetPulse(period, hightime * 1000);
            while (1 == 1)
            {
                for (hightime = 700; hightime                 
                {
                    diameter = 1500;
                    servo.SetPulse(period, hightime * 1000);;
                    factor =( diameter - minDistanceTemp) * ANGLE_STEP_SIZE * (int)System.Math.PI / 180 / 2;

                    x1 = ( factor *
                              (int)Microsoft.SPOT.Math.Sin(angle) / 1000) + (int)(display.Width / 2);
                    y1= (factor *
                              (int)Microsoft.SPOT.Math.Cos(angle) / 1000) +190;

                    //  line(x0, y0, x1, y1); //line takes too long to draw.
                    //using circles instead to show range.
                    display.SimpleGraphics.DisplayEllipse(GT.Color.Green, (uint)x1, (uint)y1, (uint)3, (uint)3);
                    angle -= ANGLE_STEP_SIZE;
                    if (angle < 90)
                    {
                        display.SimpleGraphics.Clear();
                        angle = 270;
                    }
                    System.Threading.Thread.Sleep(30);
                    minDistanceTemp = GP2D12ToCentimeters(IRRange.ReadProportion()*1000);
                    if (minDistanceTemp < minDistance || minDistance==0)
                    {                         
                        minDistance = minDistanceTemp;                        
                        minHightime = hightime;                     
                    }                 
                }             
            }         
        }         
        private UInt16 GP2D12ToCentimeters(double input)         
        {            
            UInt16 current=0;             
            if (input > 0)
            {
                //You can use Excel to calculate this function. 
                current = (UInt16)System.Math.Floor(System.Math.Pow((4187.9 / input), 1.1060));
                return current;
            }
            return current;
        }
    }

Note: if you have trouble with the Sharp IR sensor sometimes it helps to put a 30uf cap across vcc and gnd.

.Net Gadgeteer: Other Blogs/Resources

There is a growing number of online resources available for .Net Gadgeteer. I assume that everyone familiar with .Net Gadgeteer know about the following:

Here is a list of non-commercial sites:

Please feel free to forward other Gadgeteer resources.

.Net Gadgeteer: GPS Module

Seeed Studio has released a GPS module for .Net Gadgeteer. In this simple demonstration I am using Seeed Studio’s modules with the GHI’s mainboard with no issues to report. This is one of the really cool things about .Net Gadgeteer; it plays well with others. Gadgeteer is like cross vendor hardware glue that forms an eco-system. I will be talking more about that in later posts.

I am using Seeed Studio’s OLED display and showing off its vibrant colors.
Also note, I was too lazy to formet the latitude and longitude but in debug I verified it was accurate. According to the modules spec it is accurate to 2.5m. The Seeed Studio GPS module is based on the U-Blox Neo-6M GPS module.

The code is very simple:

public partial class Program
{
GTM.Seeed.GPS gps = new GTM.Seeed.GPS(8);
GTM.Seeed.OledDisplay oled = new GTM.Seeed.OledDisplay(6);

void ProgramStarted()
{
gps.InvalidPositionReceived += new GTM.Seeed.GPS.InvalidPositionReceivedHandler(gps_InvalidPositionReceived);
gps.PositionReceived += new GTM.Seeed.GPS.PositionReceivedHandler(gps_PositionReceived);
GT.Timer timer = new GT.Timer(5000);
timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
timer.Start();
}

void timer_Tick(GT.Timer timer)
{
Debug.Print("GPS last position " + gps.LastPosition + " age " + gps.LastValidPositionAge);
oled.SimpleGraphics.DisplayRectangle(GT.Color.Black, 0, GT.Color.Black, 10, 10, 120, 50);
oled.SimpleGraphics.DisplayText("GPS last position: " , Resources.GetFont(Resources.FontResources.small), GT.Color.Magenta, 10, 10);
oled.SimpleGraphics.DisplayText(" " + gps.LastPosition , Resources.GetFont(Resources.FontResources.small), GT.Color.Orange, 10, 20);
oled.SimpleGraphics.DisplayText("GPS age (days): " , Resources.GetFont(Resources.FontResources.small), GT.Color.Cyan, 10, 30);
oled.SimpleGraphics.DisplayText(" " + gps.LastValidPositionAge.Days, Resources.GetFont(Resources.FontResources.small), GT.Color.Blue, 10, 40);
}

void gps_InvalidPositionReceived(GTM.Seeed.GPS sender)
{
Debug.Print("Invalid position");
oled.SimpleGraphics.ClearNoRedraw();
oled.SimpleGraphics.DisplayText("GPS Threw: Invalid Position", Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 10, 10);
}

void gps_PositionReceived(GTM.Seeed.GPS sender, GTM.Seeed.GPS.Position position)
{
oled.SimpleGraphics.DisplayRectangle(GT.Color.Black, 0, GT.Color.Black, 10, 50, 120, 20);
oled.SimpleGraphics.DisplayText("GPS position: " , Resources.GetFont(Resources.FontResources.small), GT.Color.White, 10, 50);
oled.SimpleGraphics.DisplayText(" "+ position, Resources.GetFont(Resources.FontResources.small), GT.Color.Yellow, 10, 60);
}
}

That is all there is to it.

.Net Gadgeteer: Seeed Studio 128×128 OLED Display

This is one of the modules I was hoping to see; a small bright display. While the large 3.5″ display with touch that comes with GHI’s starter kit is impressive, for smaller devices and small robots its too large. Enter the 128×128 OLED. This display is bright and the perfect size for small device prototypes.

This OLED will be going on a robot. I am going to review a few more modules that are leading up to building a robot with .Net Gadgeteer.

The code is very simple:

display.SimpleGraphics.DisplayEllipse(GT.Color.Blue, 65, 65, 60, 50);
display.SimpleGraphics.DisplayText(".Net Gadgeteer", Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 30, 30);
display.SimpleGraphics.DisplayText(".Net Gadgeteer", Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 30, 40);
display.SimpleGraphics.DisplayText(".Net Gadgeteer", Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 30, 50);
display.SimpleGraphics.DisplayText("Rocks!!", Resources.GetFont(Resources.FontResources.small), GT.Color.Red, 30, 60);

That is all there is to it.