Main Site Documentation

Serial Communication without USB Debug Lead


#1

Hi

I have been using the code below to communicate over a serial link between my laplop and my Cerbuino Bee (COM3). It works fine, turning the onboard LED on and off with every carriage return sent, when the Debug USB is plugged in; however, as soon as I unplug the Debug USB, leaving the Cerbuino Bee to run on battery power, nothing seems to be received over COM3. Any ideas why this is happening? Surely after the code had been successfully uploaded to the Cerbuino Bee, the Debug USB is no longer required?

The serial link I am using is a pair of wires running from the DIn and DOut on a USB Xbee Dongle connected to my laptop (COM14) to the Cerbuino Bee’s Di0 and Di1 pins (COM3).

Many thanks

Ian.

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System.Text;
using System.IO.Ports;

namespace CerbuinoBeeUART_Receive_Test_3
{
    public partial class Program
    {
        // Make the serial port variable static to avoid garbage collector.
        static SerialPort UART3;
        public static byte[] rx_data = new byte[10];
        static int rx_data_Index = 0;
        const int rx_data_Max_Length = 2; //Increase this if you need longer commands.
        //LED change state booleans.
        static bool onboardLEDstate = false;
        
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            UART3 = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
            UART3.Open();
            GT.Timer timer1 = new GT.Timer(500);
            timer1.Tick += new GT.Timer.TickEventHandler(timer1_Tick);
            timer1.Start();
        }

        void timer1_Tick(GT.Timer timer)
        {
            UART3.DataReceived += new SerialDataReceivedEventHandler(UART_DataReceived);
        }

        private static void UART_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int numberOfBytesReceived = UART3.BytesToRead;
            byte[] serialBuffer = new byte[numberOfBytesReceived];
            UART3.Read(serialBuffer, 0, numberOfBytesReceived);
            //Go through each character received, collect good ones, ignore bad ones.
            for (int i = 0; i < numberOfBytesReceived; i++)
            {
                byte aByte = serialBuffer[i];
                switch (aByte)
                {
                    case 13:
                        //When we receive a carriage return, process the rx_data we have collected so far.
                        string cmd2 = new string(Encoding.UTF8.GetChars(rx_data));
                        Debug.Print("Case 13-Carriage Return Received:");
                        Debug.Print(cmd2);
                        
                        //Change state of LED when Carriage Return received.
                        onboardLEDstate = !onboardLEDstate;
                        Mainboard.SetDebugLED(onboardLEDstate);
                                                
                        //Clear command string for future commands
                        for (rx_data_Index = 0; rx_data_Index < rx_data_Max_Length; rx_data_Index++)
                            rx_data[rx_data_Index] = 0;
                        rx_data_Index = 0;
                        break;

                    default:
                        //Collect all characters other than linefeed and Carriage Return in rx_data.
                        string cmd3 = new string(Encoding.UTF8.GetChars(rx_data));
                        Debug.Print("Case Default:");
                        Debug.Print(cmd3);
                        if (rx_data_Index < rx_data_Max_Length)
                            rx_data[rx_data_Index++] = aByte;
                        break;
                }
            }
        } 
    }
}

#2

You don’t need to subscribe for the data received inside timer function to start with.


#3

Hi again,

I have rewrote the code as per below following Architect’s advice - Many thanks Architect as this is much simpler!

Thereafter, I have tried again both with and without a reset after disconnecting the Debug USB and unfortunately there is still no difference. Not sure what to try now?

Many thanks

Ian.

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System.Text;
using System.IO.Ports;

namespace CerbuinoBeeUART_Receive_Test_3
{
    public partial class Program
    {
        // Make the serial port variable static to avoid garbage collector.
        static SerialPort UART3;
        public static byte[] rx_data = new byte[10];
        static int rx_data_Index = 0;
        const int rx_data_Max_Length = 2; //Increase this if you need longer commands.
        //LED change state booleans.
        static bool onboardLEDstate = false;
        
        void ProgramStarted()
        {
            Debug.Print("Program Started");
            UART3 = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
            UART3.Open();
            GT.Timer timer1 = new GT.Timer(500);
            timer1.Tick += new GT.Timer.TickEventHandler(timer1_Tick);
            timer1.Start();
        }

        void timer1_Tick(GT.Timer timer)
        {
            int numberOfBytesReceived = UART3.BytesToRead;
            byte[] serialBuffer = new byte[numberOfBytesReceived];
            UART3.Read(serialBuffer, 0, numberOfBytesReceived);
            //Go through each character received, collect good ones, ignore bad ones.
            for (int i = 0; i < numberOfBytesReceived; i++)
            {
                byte aByte = serialBuffer[i];
                switch (aByte)
                {
                    case 13:
                        //When we receive a carriage return, process the rx_data we have collected so far.
                        string cmd2 = new string(Encoding.UTF8.GetChars(rx_data));
                        Debug.Print("Case 13-Carriage Return Received:");
                        Debug.Print(cmd2);

                        //Change state of LED when Carriage Return received.
                        onboardLEDstate = !onboardLEDstate;
                        Mainboard.SetDebugLED(onboardLEDstate);

                        //Clear command string for future commands
                        for (rx_data_Index = 0; rx_data_Index < rx_data_Max_Length; rx_data_Index++)
                            rx_data[rx_data_Index] = 0;
                        rx_data_Index = 0;
                        break;

                    default:
                        //Collect all characters other than linefeed and Carriage Return in rx_data.
                        string cmd3 = new string(Encoding.UTF8.GetChars(rx_data));
                        Debug.Print("Case Default:");
                        Debug.Print(cmd3);
                        if (rx_data_Index < rx_data_Max_Length)
                            rx_data[rx_data_Index++] = aByte;
                        break;
                }
            }
        }
    }
}

#4

Hi andre.m

I am using a 9 volt battery which seems to be fine, so I’m not convinced that it lacking in power? When I do a confidence test on an external LED by connecting to the GND and 3.3v on the Cerbuino Bee, it lights up fine.

Regards

Ian.


#5

Thanks andre.m,

The reason I have used a Timer is to avoid the message in the Debug Window approx every 10 seconds when executing suggesting that I use a Timer! Is there a better way to do this?

I have tried an external PSU at 6 volts, but still no change unfortunately. Any more ideas please?

Regards

Ian.


#6

@ IanW - hiya, can you take a picture of your physical setup.


#7

Justin,

Please see attached picture of my setup.

Regards

Ian.


#8

Hi andre.m,

I am getting about 2.25 Amps off the external power supply when set for 6 volts.

Regards

Ian.


#9

@ IanW - personally i would use datarecieved like Andre mentioned.

i use this class from Iggmoe for a similar task.

http://www.tinyclr.com/forum/topic?id=10597&page=1

the reason you got the message before is you shouldn’t have any long running code in prog started.


#10

Justin

Many thanks for the link and I’ll give this a try soon.

Just one though about my lack of comms when the Debug USB is not connected - When I tried setting up a Webserver with the ENC28 yesterday, I had the same issue when I disconnected the Debug USB, the Webpage on my laptop would not download suggesting there was not a connection. Is it possible that something else may be wrong here other than the power supply?

Regards

Ian


#11

Ian, i thought it sounded familiar…
If the link i sent doesn’t help have a read thru this thread.
http://www.tinyclr.com/forum/topic?id=7692&page=1#msg76824


#12

Hi Justin,

I tried the code at the link you gave me (altered slightly for NETMF 4.2) as per below. Unfortunately, it is still not communicating when the Debug USB is not in. I also keep getting:

WARN: Total initialization time exceeds 10 seconds.
: ProgramStarted is blocking execution, which means events and timers will not run properly.
: Make sure not to use blocking code such as while(true) - use a GT.Timer instead.

Regards

Ian.

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System.Text;
using System.IO.Ports;
using YOUR_NAMESPACE_HERE;

namespace CerbuinoBeeUART_Receive_Test_5
{
    public partial class Program
    {
        public static SimpleSerial MySerialPort = new SimpleSerial("COM3", 9600, Parity.None, 8, StopBits.One);

        //LED change state booleans.
        static bool onboardLEDstate = false;

        void ProgramStarted()
        {
            Debug.Print("Program Started");
            // The event handler must be added AFTER opening the serial port, otherwise the event will
            // not fire in Release mode (it will only fire during Debug). This is a NETMF oddity.
            MySerialPort.Open();
            MySerialPort.DataReceived += new SerialDataReceivedEventHandler(MySerialPort_DataReceived);

            // Nothing left to do in Main(), so put it to sleep.
            Thread.Sleep(Timeout.Infinite);
        }

        void MySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Cast the event source as a SimpleSerial object
            SimpleSerial sp = sender as SimpleSerial;

            // Extract an array of complete sentences from the port.
            // Only complete, properly terminated sentences are included in this array.
            string[] sentences = sp.Deserialize();

            // Pull each sentence from the array and perform further processing
            for (int index = 0; index < sentences.Length; index++)
            {
                string sentence = sentences[index];
                Debug.Print(sentence);
               
                //Change state of LED when Carriage Return received.
                onboardLEDstate = !onboardLEDstate;
                Mainboard.SetDebugLED(onboardLEDstate);
            }
        }
    }
}

#13

Hi andre.m,

Thanks, thant solves the ‘WARN: Total initialization time exceeds 10 seconds’ problem, but no joy with the lack of comms once the Debig USB has been removed.

Regards

Ian.


#14

Try using plain NETMF SerialPort instead of SimpleSerial.


#15

Thank Architect, but same problem is still there.

Regards

Ian.

This is my new code:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System.Text;
using System.IO.Ports;

namespace CerbuinoBee_UART_Receive_Test_1b
{
    public partial class Program
    {
        public static SerialPort UART3 = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        public static byte[] rx_data = new byte[10];
        //LED change state booleans.
        static bool onboardLEDstate = false;

        void ProgramStarted()
        {
            Debug.Print("Program Started");
            // The event handler must be added AFTER opening the serial port, otherwise the event will
            // not fire in Release mode (it will only fire during Debug). This is a NETMF oddity.
            UART3.Open();
            UART3.DataReceived += new SerialDataReceivedEventHandler(UART3_DataReceived);
        }

        void UART3_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            UART3.Read(rx_data, 0, UART3.BytesToRead);
            string receivedDataAsString = new string(Encoding.UTF8.GetChars(rx_data));
            Debug.Print(receivedDataAsString);
            //Change state of LED when data received.
            onboardLEDstate = !onboardLEDstate;
            Mainboard.SetDebugLED(onboardLEDstate);
        }
    }
}

#16

And so, does it work WITHOUT the debug.print in the datarecieved event handler?


#17

Brett,

No, still not working.

Regards

Ian.


#18

Hi andre.m,

I have already been resetting after disconnecting the Debug USB, but my code is as follows.

Regards

Ian.

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Microsoft.SPOT.Hardware;
using System.Text;
using System.IO.Ports;

namespace CerbuinoBee_UART_Receive_Test_1b
{
    public partial class Program
    {
        public static SerialPort UART3 = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        public static byte[] rx_data = new byte[10];
        //LED change state booleans.
        static bool onboardLEDstate = false;

        void ProgramStarted()
        {
            Debug.Print("Program Started");
            // The event handler must be added AFTER opening the serial port, otherwise the event will
            // not fire in Release mode (it will only fire during Debug). This is a NETMF oddity.
            UART3.Open();
            UART3.DataReceived += new SerialDataReceivedEventHandler(UART3_DataReceived);
        }

        void UART3_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            UART3.Read(rx_data, 0, UART3.BytesToRead);
            string receivedDataAsString = new string(Encoding.UTF8.GetChars(rx_data));
            
            //Change state of LED when data received.
            onboardLEDstate = !onboardLEDstate;
            Mainboard.SetDebugLED(onboardLEDstate);
        }
    }
}

#19

OK, here’s one more thing to try. Reverse the subscribe to event and the uart open().


#20

are you sure it’s the Panda thats not talking??
are you sure your PC is working…