locked
[SOLVED] Controller and Serial Communication RRS feed

  • Question

  • I am running on MS RDS 4 with Visual Studio C# 2010 Express. I am trying to send data to an Arduino Mega 2560. I know this can be done as I have ran other code using the Arduino sending data from some sensors and having some c# code in visual studio to read and interpret it. Though I was using a console application to do that and that is different from a DSS Service (4.0) so I'm assuming how to do it is different than just the console application way, since the console application is different than the Windows Forms Application.  Now I'm trying to do the opposite and send data from a controller to the Arduino Mega.

    Here is the code I'm using in visual studio

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.Ccr.Core;
    using Microsoft.Dss.Core.Attributes;
    using Microsoft.Dss.ServiceModel.Dssp;
    using Microsoft.Dss.ServiceModel.DsspServiceBase;
    using W3C.Soap;
    // maybe a diffzerent way of activating the controller
    using controller = Microsoft.Robotics.Services.GameController.Proxy;
    using System.IO.Ports;
    using System.Threading;
    
    namespace XboxControllerTestGC
    {
    	[Contract(Contract.Identifier)]
    	[DisplayName("XboxControllerTestGC")]
    	[Description("XboxControllerTestGC service (no description provided)")]
    	class XboxControllerTestGCService : DsspServiceBase
    	{
    		[ServiceState]
    		XboxControllerTestGCState _state = new XboxControllerTestGCState();
    		
    		[ServicePort("/XboxControllerTestGC", AllowMultipleInstances = true)]
    		XboxControllerTestGCOperations _mainPort = new XboxControllerTestGCOperations();
    
            [Partner("GameController", Contract = controller.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
            private controller.GameControllerOperations _controllerPort = new controller.GameControllerOperations();
            private controller.GameControllerOperations _controllerNotification = new controller.GameControllerOperations();
    
    		public XboxControllerTestGCService(DsspServiceCreationPort creationPort)
    			: base(creationPort)
    		{
    		}
    
    
            SerialPort _serial = new SerialPort();
    
    		protected override void Start()
    		{
    			
    			// 
    			// Add service specific initialization here
    			// 
                //*
                _serial.PortName = "COM4";
                _serial.BaudRate = 115200;
                _serial.DtrEnable = true;
                _serial.Open();//*/
    
                _controllerPort.Subscribe(_controllerNotification);
                Activate(Arbiter.Receive<controller.UpdateButtons>(true, _controllerNotification, Buttons));
                Activate(Arbiter.Receive<controller.UpdateAxes>(true, _controllerNotification, Sticks));
    
    			base.Start();
    
                //Thread.Sleep(100);
                //*
                Console.WriteLine(" Pressing A should make the robot move ");
                Console.WriteLine(" Then from there you should be able to ");
                Console.WriteLine(" Use the XBox 360 wireless controller  ");
                Console.WriteLine(" To move the robot. ");//*/
                //*
                Console.WriteLine(" The Serial Port is open?: {0}", _serial.IsOpen);
                _serial.Write("Hello");
                _serial.DataReceived += Read;//*/
                //System.Diagnostics.Debug.WriteLine("Something");
                //System.Diagnostics.Trace.WriteLine("LISTEN!");
    		}
    
            private void Buttons(controller.UpdateButtons btn)
            {
                Boolean[] pressed = new Boolean[btn.Body.Pressed.Count];
                pressed = btn.Body.Pressed.ToArray();
                /*for (int i = 0; i < btn.Body.Pressed.Count; i++)
                {
                    if (pressed[i] == true)
                    {
                        Console.Write("{0}  ", i);
                    }
                }
                Console.Write("\n");
                //*/
                if (pressed[0] == true)
                {
                    Console.Write("A");
                    _serial.Write("A");
                }
                if (pressed[1] == true)
                {
                    Console.Write("B");
                    _serial.Write("B");
                }
            }
    
            private void Sticks(controller.UpdateAxes stk)
            {
                Console.Write(" L");
                //_serial.Write(" L");
                //Console.WriteLine(stk.Body.X);
                Console.Write(stk.Body.Y);
                //_serial.Write(stk.Body.Y.ToString());
    
                Console.Write(" R");
                //_serial.Write(" R");
                //Console.WriteLine(stk.Body.Rx);
                Console.Write(stk.Body.Ry);
                //_serial.Write(stk.Body.Ry.ToString());
            }
    
            //*
            private void Read(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                Console.WriteLine("I MADE IT TO READ");
                try
                {
                    string msg = _serial.ReadLine();
                    Console.WriteLine(msg);
                }
                catch (TimeoutException)
                {
                    Console.WriteLine("Received Exception");
                }
            }//*/
    	}
    }
    

    Its using the Game Controller class instead of the XInputController class. I am using an Xbox 360 Controller though so if you think using the XInput Controller would be easier that's fine too. But my problem is I don't believe it is sending its data to the Arduino, or if it is it's not receiving the data I'm having the Arduino echoing back at it. I know the controller is working though because I can do the dsshost /p:50000 and /t:50001 and run this with its manifest and see the controller output its data. But it's not printing anything from the Arduino. when running it straight from Visual Studio the outcome is as followed.

    * Service Started [11/12/2014 16:57:32][http://127.0.0.1:50000/directory]
    * Service Started [11/12/2014 16:57:32][http://127.0.0.1:50000/constructor]
    * Service Started [11/12/2014 16:57:32][http://127.0.0.1:50000/console/output]
    * Service Started [11/12/2014 16:57:32][http://127.0.0.1:50000/gamecontroller/ee9118dc-a7cc-4d3f-8f2f-eec8eadce452]
    * Service Started [11/12/2014 16:57:32][http://127.0.0.1:50000/xboxcontrollertestgc/5dad2c4f-fbe4-4ab5-898e-2fb74802c272]
    Pressing A should make the robot move
    Then from there you should be able to
    Use the XBox 360 wireless controller
    To move the robot.
    The Serial Port is open?: True
    I MADE IT TO READ

    The only difference if ran using dsshost and starting it manually that way is after all that I'll get L# R# and A and B when sticks are moved/ pressed respectively.

    I believe that if I did it right it shouldn't make it to read immediately, since my arduino is just echoing the inputs it gets back at it so the serial port shouldn't have received any data. I'm also fairly sure that I'm not getting my desired results because of the code posted above.

    Thanks in advance and if more information is needed please let me know I'll try my best to provide it!



    • Edited by smorgisborg Thursday, November 13, 2014 3:53 PM solved it.
    Wednesday, November 12, 2014 5:28 PM

Answers

  • I'm going go a head and just post it anyway just in case someone does want to see it and I don't read their post.

    Arduino coding used to test this:

    char incomingByte;
    char Byte[50];
    int i;
    
    void setup()
    {
      Serial.begin(115200);
    }
    void loop()
    {
      if (Serial.available() > 0)
      {
        incomingByte = Serial.read();
        //*
        Byte[i] = incomingByte;
        if (incomingByte == '.')
        {
          Byte[i] = (char)0;
          Serial.println(Byte);
          i = -1;
        }   
        i = i + 1;
        //*/
        //Serial.print(incomingByte);
        //Serial.println();
      }
    }

    C# code in Visual Studio:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.Ccr.Core;
    using Microsoft.Dss.Core.Attributes;
    using Microsoft.Dss.ServiceModel.Dssp;
    using Microsoft.Dss.ServiceModel.DsspServiceBase;
    using W3C.Soap;
    // maybe a diffzerent way of activating the controller
    using controller = Microsoft.Robotics.Services.GameController.Proxy;
    using System.IO.Ports;
    using System.Threading;
    
    namespace XboxControllerTestGC
    {
    	[Contract(Contract.Identifier)]
    	[DisplayName("XboxControllerTestGC")]
    	[Description("XboxControllerTestGC service (no description provided)")]
    	class XboxControllerTestGCService : DsspServiceBase
    	{
    		[ServiceState]
    		XboxControllerTestGCState _state = new XboxControllerTestGCState();
    		
    		[ServicePort("/XboxControllerTestGC", AllowMultipleInstances = true)]
    		XboxControllerTestGCOperations _mainPort = new XboxControllerTestGCOperations();
    
            [Partner("GameController", Contract = controller.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
            private controller.GameControllerOperations _controllerPort = new controller.GameControllerOperations();
            private controller.GameControllerOperations _controllerNotification = new controller.GameControllerOperations();
    
    		public XboxControllerTestGCService(DsspServiceCreationPort creationPort)
    			: base(creationPort)
    		{
    		}
    
    
            SerialPort _serial = new SerialPort();
            Boolean _continue;
            int prevL = 0;
            int prevR = 0;
            
    		protected override void Start()
    		{
    			
    			// 
    			// Add service specific initialization here
    			// 
                //*
                Thread reading = new Thread(Read);
                _continue = true;
    
                _serial.PortName = "COM4";
                _serial.BaudRate = 115200;
                _serial.DtrEnable = true;
                _serial.Open();//*/
    
                _controllerPort.Subscribe(_controllerNotification);
                Activate(Arbiter.Receive<controller.UpdateButtons>(true, _controllerNotification, Buttons));
                Activate(Arbiter.Receive<controller.UpdateAxes>(true, _controllerNotification, Sticks));
                
                reading.Start();
    
    			base.Start();
    
                //Thread.Sleep(100);
                /*
                Console.WriteLine(" Pressing A should make the robot move ");
                Console.WriteLine(" Then from there you should be able to ");
                Console.WriteLine(" Use the XBox 360 wireless controller  ");
                Console.WriteLine(" To move the robot. ");//*/
                /*
                Console.WriteLine(" The Serial Port is open?: {0}", _serial.IsOpen);
                _serial.Write("Hello");
                _serial.DataReceived += Read;//*/
                //System.Diagnostics.Debug.WriteLine("Something");
                //System.Diagnostics.Trace.WriteLine("LISTEN!");
    		}
    
            private void Buttons(controller.UpdateButtons btn)
            {
                Boolean[] pressed = new Boolean[btn.Body.Pressed.Count];
                pressed = btn.Body.Pressed.ToArray();
                /*for (int i = 0; i < btn.Body.Pressed.Count; i++)
                {
                    if (pressed[i] == true)
                    {
                        Console.Write("{0}  ", i);
                    }
                }
                Console.Write("\n");
                //*/
                if (pressed[0] == true)
                {
                    //Console.Write("A");
                    _serial.Write("A.");
                }
                if (pressed[1] == true)
                {
                    //Console.Write("B");
                    _serial.Write("B.");
                }
            }
    
            private void Sticks(controller.UpdateAxes stk)
            {
                //Console.Write(" L");
                //Console.WriteLine(stk.Body.X);
                //Console.Write(stk.Body.Y);
                if (stk.Body.Y != prevL || stk.Body.Ry != prevR)
                {
                    _serial.Write("L " + stk.Body.Y.ToString());
    
                    //Console.Write(" R");
                    //Console.WriteLine(stk.Body.Rx);
                    //Console.Write(stk.Body.Ry);
                    _serial.Write(" R " + stk.Body.Ry.ToString() + ".");
    
                    prevL = stk.Body.Y;
                    prevR = stk.Body.Ry;
                }
            }
    
            /*
            private void Read(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                Console.WriteLine("I MADE IT TO READ");
                try
                {
                    string msg = _serial.ReadLine();
                    Console.WriteLine(msg);
                }
                catch (TimeoutException)
                {
                    Console.WriteLine("Received Exception");
                }
            }//*/
    
            public void Read()
            {
                while (_continue)
                {
                    try
                    {
                        string msg = _serial.ReadLine();
                        Console.WriteLine(msg);
                    }
                    catch (TimeoutException)
                    {
                    }
                }
            }
    	}
    }
    
    

    • Marked as answer by smorgisborg Thursday, November 13, 2014 3:53 PM
    Thursday, November 13, 2014 3:52 PM

All replies

  • Thanks to all who took the time to read this and were possibly going to try to help. I have gotten it to work now at least in such a way i can work with. I can post it up as a solution if someone would like with both Arduino and C# code. Just to note that I only got it to work doing the dsshost32 /p:50000 /t:50001 but I'm happy with that since now the arduino will echo the controller's inputs back, which means i can start implementing what i desire with it. Thanks again to all who took their time to read this.
    Thursday, November 13, 2014 3:16 PM
  • I'm going go a head and just post it anyway just in case someone does want to see it and I don't read their post.

    Arduino coding used to test this:

    char incomingByte;
    char Byte[50];
    int i;
    
    void setup()
    {
      Serial.begin(115200);
    }
    void loop()
    {
      if (Serial.available() > 0)
      {
        incomingByte = Serial.read();
        //*
        Byte[i] = incomingByte;
        if (incomingByte == '.')
        {
          Byte[i] = (char)0;
          Serial.println(Byte);
          i = -1;
        }   
        i = i + 1;
        //*/
        //Serial.print(incomingByte);
        //Serial.println();
      }
    }

    C# code in Visual Studio:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.Ccr.Core;
    using Microsoft.Dss.Core.Attributes;
    using Microsoft.Dss.ServiceModel.Dssp;
    using Microsoft.Dss.ServiceModel.DsspServiceBase;
    using W3C.Soap;
    // maybe a diffzerent way of activating the controller
    using controller = Microsoft.Robotics.Services.GameController.Proxy;
    using System.IO.Ports;
    using System.Threading;
    
    namespace XboxControllerTestGC
    {
    	[Contract(Contract.Identifier)]
    	[DisplayName("XboxControllerTestGC")]
    	[Description("XboxControllerTestGC service (no description provided)")]
    	class XboxControllerTestGCService : DsspServiceBase
    	{
    		[ServiceState]
    		XboxControllerTestGCState _state = new XboxControllerTestGCState();
    		
    		[ServicePort("/XboxControllerTestGC", AllowMultipleInstances = true)]
    		XboxControllerTestGCOperations _mainPort = new XboxControllerTestGCOperations();
    
            [Partner("GameController", Contract = controller.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExisting)]
            private controller.GameControllerOperations _controllerPort = new controller.GameControllerOperations();
            private controller.GameControllerOperations _controllerNotification = new controller.GameControllerOperations();
    
    		public XboxControllerTestGCService(DsspServiceCreationPort creationPort)
    			: base(creationPort)
    		{
    		}
    
    
            SerialPort _serial = new SerialPort();
            Boolean _continue;
            int prevL = 0;
            int prevR = 0;
            
    		protected override void Start()
    		{
    			
    			// 
    			// Add service specific initialization here
    			// 
                //*
                Thread reading = new Thread(Read);
                _continue = true;
    
                _serial.PortName = "COM4";
                _serial.BaudRate = 115200;
                _serial.DtrEnable = true;
                _serial.Open();//*/
    
                _controllerPort.Subscribe(_controllerNotification);
                Activate(Arbiter.Receive<controller.UpdateButtons>(true, _controllerNotification, Buttons));
                Activate(Arbiter.Receive<controller.UpdateAxes>(true, _controllerNotification, Sticks));
                
                reading.Start();
    
    			base.Start();
    
                //Thread.Sleep(100);
                /*
                Console.WriteLine(" Pressing A should make the robot move ");
                Console.WriteLine(" Then from there you should be able to ");
                Console.WriteLine(" Use the XBox 360 wireless controller  ");
                Console.WriteLine(" To move the robot. ");//*/
                /*
                Console.WriteLine(" The Serial Port is open?: {0}", _serial.IsOpen);
                _serial.Write("Hello");
                _serial.DataReceived += Read;//*/
                //System.Diagnostics.Debug.WriteLine("Something");
                //System.Diagnostics.Trace.WriteLine("LISTEN!");
    		}
    
            private void Buttons(controller.UpdateButtons btn)
            {
                Boolean[] pressed = new Boolean[btn.Body.Pressed.Count];
                pressed = btn.Body.Pressed.ToArray();
                /*for (int i = 0; i < btn.Body.Pressed.Count; i++)
                {
                    if (pressed[i] == true)
                    {
                        Console.Write("{0}  ", i);
                    }
                }
                Console.Write("\n");
                //*/
                if (pressed[0] == true)
                {
                    //Console.Write("A");
                    _serial.Write("A.");
                }
                if (pressed[1] == true)
                {
                    //Console.Write("B");
                    _serial.Write("B.");
                }
            }
    
            private void Sticks(controller.UpdateAxes stk)
            {
                //Console.Write(" L");
                //Console.WriteLine(stk.Body.X);
                //Console.Write(stk.Body.Y);
                if (stk.Body.Y != prevL || stk.Body.Ry != prevR)
                {
                    _serial.Write("L " + stk.Body.Y.ToString());
    
                    //Console.Write(" R");
                    //Console.WriteLine(stk.Body.Rx);
                    //Console.Write(stk.Body.Ry);
                    _serial.Write(" R " + stk.Body.Ry.ToString() + ".");
    
                    prevL = stk.Body.Y;
                    prevR = stk.Body.Ry;
                }
            }
    
            /*
            private void Read(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                Console.WriteLine("I MADE IT TO READ");
                try
                {
                    string msg = _serial.ReadLine();
                    Console.WriteLine(msg);
                }
                catch (TimeoutException)
                {
                    Console.WriteLine("Received Exception");
                }
            }//*/
    
            public void Read()
            {
                while (_continue)
                {
                    try
                    {
                        string msg = _serial.ReadLine();
                        Console.WriteLine(msg);
                    }
                    catch (TimeoutException)
                    {
                    }
                }
            }
    	}
    }
    
    

    • Marked as answer by smorgisborg Thursday, November 13, 2014 3:53 PM
    Thursday, November 13, 2014 3:52 PM