Line Tracer Mission using I2C


1. Download and open C# project file
  1. Download source code.

    LineTracer.Sample1.zip



2. C# source code for LineTracer.Sample1
  1. Program.cs

      
    
    using System;
    
    using Microsoft.SPOT;
    using Microsoft.SPOT.Input;
    using Microsoft.SPOT.Presentation;
    using Microsoft.SPOT.Presentation.Controls;
    using Microsoft.SPOT.Hardware;
    
    using SPL.Script.Engine;
    
    namespace SPLMFConsoleWindow1
    {
        public class Program : Microsoft.SPOT.Application
        {
            public static void Main()
            {
                Program myApplication = new Program();
    
                Window mainWindow = myApplication.CreateWindow();
    
                GPIOButtonInputProvider inputProvider = new GPIOButtonInputProvider(null);
    
                myApplication.Run(mainWindow);
            }
    
            private Window mainWindow;
    
            //##########################  Sample Code  #################################
            private ConsoleWindow _consoleWindow;
    
            private I2CDevice _device = null;
            private I2CDevice _i2c2 = null;
            private I2CDevice _i2c3 = null;
            private I2CDevice _i2c4 = null;
            //##########################################################################
    
            public Window CreateWindow()
            {
                mainWindow = new Window();
                mainWindow.Height = SystemMetrics.ScreenHeight;
                mainWindow.Width = SystemMetrics.ScreenWidth;
    
                //##########################  Sample Code  #################################
                Font font = Resources.GetFont(Resources.FontResources.small);
                _consoleWindow = new ConsoleWindow(font);
    
                mainWindow.Child = _consoleWindow;
                //##########################################################################
    
                mainWindow.AddHandler(Buttons.ButtonUpEvent, new ButtonEventHandler(OnButtonUp), false);
    
                mainWindow.Visibility = Visibility.Visible;
    
                Buttons.Focus(mainWindow);
    
                //##########################  Sample Code  #################################
                _consoleWindow.WriteLine("Push Select-Button to make a robot turn.");
                //##########################################################################
    
    
                //##########################  Sample Code  #################################
                I2CDevice.Configuration config = new I2CDevice.Configuration(
                                58,
                                100
                                );
    
                _device = new I2CDevice(config);
    
    
                I2CDevice.Configuration i2c2_config = new I2CDevice.Configuration(
                                60,
                                100
                                );
    
                _i2c2 = new I2CDevice(i2c2_config);
    
                I2CDevice.Configuration i2c3_config = new I2CDevice.Configuration(
                                62,
                                100
                                );
    
                _i2c3 = new I2CDevice(i2c3_config);
    
                I2CDevice.Configuration i2c4_config = new I2CDevice.Configuration(
                                64,
                                100
                                );
    
                _i2c4 = new I2CDevice(i2c4_config);
    
                System.Threading.Thread serialReaderThread = new System.Threading.Thread(i2c2_Reader);
                serialReaderThread.Start();
    
                //##########################################################################
    
                return mainWindow;
            }
    
            private void OnButtonUp(object sender, ButtonEventArgs e)
            {
                //##########################  Sample Code  #################################
                if (e.Button == Microsoft.SPOT.Hardware.Button.VK_SELECT)
                {
                    byte[] wBuff = new byte[3];
                    wBuff[0] = 4;
                    wBuff[1] = 90;     //-0.1
                    wBuff[2] = 110;     //0.1
    
                    I2CDevice.I2CWriteTransaction wTr = _device.CreateWriteTransaction(wBuff);
                    I2CDevice.I2CTransaction[] wTrArr = new I2CDevice.I2CTransaction[] { wTr };
    
                    //Go Forwards
                    int count = _device.Execute(wTrArr, 1000);
    
                    _consoleWindow.WriteLine("Turn left");
                }
                //##########################################################################
            }
    
    
            //##########################  Sample Code  #################################
            private void i2c2_Reader()
            {
                byte[] rBuff2 = new byte[3];
                byte[] rBuff3 = new byte[3];
                byte[] rBuff4 = new byte[3];
    
                byte[] wBuff = new byte[3];
    
                int c2 = 765;
                int c3 = 765;
                int c4 = 765;
    
                int count = 0;
    
                I2CDevice.I2CReadTransaction rTr2 = _device.CreateReadTransaction(rBuff2);
                I2CDevice.I2CTransaction[] rTrArr2 = new I2CDevice.I2CTransaction[] { rTr2 };
    
                I2CDevice.I2CReadTransaction rTr3 = _device.CreateReadTransaction(rBuff3);
                I2CDevice.I2CTransaction[] rTrArr3 = new I2CDevice.I2CTransaction[] { rTr3 };
    
                I2CDevice.I2CReadTransaction rTr4 = _device.CreateReadTransaction(rBuff4);
                I2CDevice.I2CTransaction[] rTrArr4 = new I2CDevice.I2CTransaction[] { rTr4 };
    
                I2CDevice.I2CWriteTransaction wTr = _device.CreateWriteTransaction(wBuff);
                I2CDevice.I2CTransaction[] wTrArr = new I2CDevice.I2CTransaction[] { wTr };
    
                int skip_count = 0;
    
                while (true)
                {
                    try
                    {
                        count = _i2c2.Execute(rTrArr2, 1000);
                        count = _i2c3.Execute(rTrArr3, 1000);
                        count = _i2c4.Execute(rTrArr4, 1000);
    
                        if (rBuff2 != null && rBuff3 != null && rBuff4 != null)
                        {
                            c2 = rBuff2[0] + rBuff2[1] + rBuff2[2];
                            c3 = rBuff3[0] + rBuff3[1] + rBuff3[2];
                            c4 = rBuff4[0] + rBuff4[1] + rBuff4[2];
    
                            if (c2 <= 10)
                                c2 = 765;
    
                            if (c3 <= 10)
                                c3 = 0;
    
                            if (c4 <= 10)
                                c4 = 765;
    
                            if (skip_count == 0)
                            {
                                if (c2 < 255 && c4 >= 255)
                                {
                                    //turn left
                                    wBuff[0] = 2;
                                    wBuff[1] = 130;	//130-100
                                    wBuff[2] = 110;	//0.1			
                                    count = _device.Execute(wTrArr, 1000);
    
                                    skip_count = 3;
                                }
                                else if (c2 >= 255 && c4 < 255)
                                {
                                    //turn right
                                    wBuff[0] = 2;
                                    wBuff[1] = 70;	//70-100
                                    wBuff[2] = 110;	//0.1			
                                    count = _device.Execute(wTrArr, 1000);
    
                                    skip_count = 3;
                                }
                                else if (c2 >= 255 && c3 >= 255 && c3 >= 255)
                                {
                                    //turn right
                                    wBuff[0] = 2;
                                    wBuff[1] = 70;	//70-100
                                    wBuff[2] = 110;	//0.1			
                                    count = _device.Execute(wTrArr, 1000);
    
                                    skip_count = 3;
                                }
                                else
                                {
                                    //go forwards
                                    wBuff[0] = 4;
                                    wBuff[1] = 110;	//0.1
                                    wBuff[2] = 110;	//0.1			
                                    count = _device.Execute(wTrArr, 1000);
    
                                    skip_count = 1;
                                }
                            }
    
                            if (skip_count == 1)
                            {
                                //go forwards
                                wBuff[0] = 4;
                                wBuff[1] = 110;	//0.1
                                wBuff[2] = 110;	//0.1			
                                count = _device.Execute(wTrArr, 1000);
                            }
    
                            if (skip_count > 0)
                                skip_count--;
    
                        }
                    }
                    catch { }
    
                    System.Threading.Thread.Sleep(300);
                }
            }
    
            private void LogInfo(string log)
            {
                this.Dispatcher.BeginInvoke(
                    new DispatcherOperationCallback(
                        delegate(object report)
                        {
                            _consoleWindow.WriteLine(log);
                            return null;
                        }
                        ), null
                    );
            }
            //##########################################################################
        }
    }
    
    
      



3. Execute C# project
  1. Open "Properties" page of C# project.

  2. Choose ".NET Micro Framework" tab.

  3. Select "SPLMFConsoleEmulator" from the emulator list.



  4. Press "F5" key to run sample code.




4. Launch simulation environment
  1. Start "SPL script editor for MSRDS" and add SPL simulation script.

  2. Add script on the editor as follows.



      
    MFEmulator    emul1
    	/Procedure_I2CWrite:proc_i2c_write
    
    StartSimulationEngine  "SimState/basicsim.xml"
    
    AddNewEntity  whitepanel  	/Position:0  0.005  0
    
    AddBoxShape
    	/Dimensions:10  0.01  10  	/Mass:100
    	/DiffuseColor:1  1  1  1
    
    AddBoxShape
    	/Dimensions:4.3  0.001  0.3  	/Mass:0.1
    	/Position:0    0.006    2
    	/DiffuseColor:0    0    0    1
    
    AddBoxShape
    	/Dimensions:4.3  0.001  0.3  	/Mass:0.1
    	/Position:0    0.006    -2
    	/DiffuseColor:0    0    0    1
    
    AddBoxShape
    	/Dimensions:0.3  0.001  4  	/Mass:0.1
    	/Position:2    0.006    0
    	/DiffuseColor:0    0    0    1
    
    AddBoxShape
    	/Dimensions:0.3  0.001  4  	/Mass:0.1
    	/Position:-2    0.006    0
    	/DiffuseColor:0    0    0    1 
    
    FlushScript  
    
    
    AddDifferentialDriveEntity  base1
    	/Position:0  0.01  2
    	/Orientation:0  90  0
    
    AddColorSensorEntity  color1
    	/Position:-0.2  0.2  -0.3
    	/ParentEntity:base1
    	/Orientation:-90    0    0
    	/Procedure_SensorNotify:proc_color1
    
    AddColorSensorEntity  color2
    	/Position:0  0.2  -0.3
    	/ParentEntity:base1
    	/Orientation:-90    0    0
    	/Procedure_SensorNotify:proc_color2
    
    AddColorSensorEntity  color3
    	/Position:0.2  0.2  -0.3
    	/ParentEntity:base1
    	/Orientation:-90    0    0
    	/Procedure_SensorNotify:proc_color3
    
    FlushScript  
    
    procedure  proc_color1
    
    	r = value.NormalizedAverageRed	//0.0 ~ 1.0
    	g = value.NormalizedAverageGreen	//0.0 ~ 1.0
    	b = value.NormalizedAverageBlue	//0.0 ~ 1.0
    	
    	r = r * 255	//convert to 0 ~ 255
    	g = g * 255	//convert to 0 ~ 255
    	b = b * 255	//convert to 0 ~ 255
    	
    	//convert type as byte
    	sendBytes = Util.CreateArrayByte(3)
    	sendBytes[0] = Util.ToByte(r)	
    	sendBytes[1] = Util.ToByte(g)	
    	sendBytes[2] = Util.ToByte(b)	
    		
    	emul1.SetI2CReadBuffer("i2c2", sendBytes)
    			
    end 
    
    procedure  proc_color2
    
    	r = value.NormalizedAverageRed	//0.0 ~ 1.0
    	g = value.NormalizedAverageGreen	//0.0 ~ 1.0
    	b = value.NormalizedAverageBlue	//0.0 ~ 1.0
    	
    	r = r * 255	//convert to 0 ~ 255
    	g = g * 255	//convert to 0 ~ 255
    	b = b * 255	//convert to 0 ~ 255
    	
    	//convert type as byte
    	sendBytes = Util.CreateArrayByte(3)
    	sendBytes[0] = Util.ToByte(r)	
    	sendBytes[1] = Util.ToByte(g)	
    	sendBytes[2] = Util.ToByte(b)	
    		
    	emul1.SetI2CReadBuffer("i2c3", sendBytes)
    			
    end 
    
    procedure  proc_color3
    
    	r = value.NormalizedAverageRed	//0.0 ~ 1.0
    	g = value.NormalizedAverageGreen	//0.0 ~ 1.0
    	b = value.NormalizedAverageBlue	//0.0 ~ 1.0
    	
    	r = r * 255	//convert to 0 ~ 255
    	g = g * 255	//convert to 0 ~ 255
    	b = b * 255	//convert to 0 ~ 255
    	
    	//convert type as byte
    	sendBytes = Util.CreateArrayByte(3)
    	sendBytes[0] = Util.ToByte(r)	
    	sendBytes[1] = Util.ToByte(g)	
    	sendBytes[2] = Util.ToByte(b)	
    		
    	emul1.SetI2CReadBuffer("i2c4", sendBytes)
    			
    end 
    
    procedure  proc_i2c_write
    	
    	ready_flag = true
    
    	if (value.Id == "i2c1")
    	{
    		command_type = value.ReceivedBytes[0]
    		
    		if (command_type == 1)
    		{		
    			distance = value.ReceivedBytes[1]
    			power = value.ReceivedBytes[2]
    	
    			power = power - 100
    
    			distance = Util.ToDouble(distance / 10.0)
    			power = Util.ToDouble(power / 100.0)
    
    			print "Distance -> " + distance.ToString() + " m / Power -> " + power.ToString()
    			
    			base1.GoTo(distance, power)
    		}
    		else if (command_type == 2)
    		{		
    			degrees = value.ReceivedBytes[1]
    			power = value.ReceivedBytes[2]
    	
    			degrees = degrees - 100
    			power = power - 100
    
    			degrees = Util.ToDouble(degrees)
    			power = Util.ToDouble(power / 100.0)
    
    			print "Degrees -> " + degrees.ToString() + " / Power -> " + power.ToString()
    			
    			base1.Turn(degrees, power)
    		}
    		else if (command_type == 4)
    		{		
    			left_power = value.ReceivedBytes[1]
    			right_power = value.ReceivedBytes[2]
    	
    			left_power = left_power - 100
    			right_power = right_power - 100
    
    			left_power = Util.ToDouble(left_power / 100.0)
    			right_power = Util.ToDouble(right_power / 100.0)
    
    			print "Left -> " + left_power.ToString() + " / Right -> " + right_power.ToString()
    			
    			base1.Go(left_power, right_power)
    		}
    	}
    
    end  
    
      


  3. Save script.

  4. Press "F5" key or click "Run" icon.



5. Start demo
  1. Click Select-Button to start demo.



  2. You can see a mobile robot move itself through line.