Unable to access COM port

Project: Windows Form App, MS Visual Studio 2010 Professional

Two webcams, one laser, four servos and a Pololu Maestro 6 channel USB device. One cam and the laser measures range(two servos), second webcam automatically tracks laserdot(two servos). Pololu software simulates two COM ports (used to send commands to the servos, these pops up as COM 3 (Serial) and COM4 (TTL)).

Problem:
“An exception of type ‘System.UnauthorizedAccessException’ occurred in System.dll but was not handled in user code” “Additional information: Ingen tilgang til porten COM3”. (“Ingen tilgang til porten COM3” -translated: “Access denied to port COM3”)
Without Debugging: The application runs, then freezes after some time, no error shown. (The time varies)
With Debugging: The application runs for a short time, then the above error pops up. (Time also varies)
The error occurs only when I enable either the tracking or the manual control (by slidebar) for the laserrange servos. I have implemented a manual control of the servos, where it is only possible to control one at a time…this does not seem to give problems…

Here is the code for the servoclass:

namespace LaserstyrtKanon
{
    class servoklasse
    {
        public void MiniSSC(string ComPort, int BaudRate, int ServoNummer, int ServoPos) //Mini-SSC protocol
        {
            const double MIN_POS = 0
                     , MAX_POS = 255;

            if (ServoPos < MIN_POS)
            {
                throw new ArgumentException("Servoposisjonen er mindre enn minimum tillatt!");
            }
            else if (ServoPos > MAX_POS)
            {
                throw new ArgumentException("Servoposisjonen er større enn maksimum tillatt.");
            }
           SerialPort port = new SerialPort(ComPort, BaudRate, Parity.None, 8, StopBits.One);
            port.Handshake = Handshake.None;
            port.Open();            <----this is where the Debugger points the error at ----            
            string ServoPosHex = ServoPos.ToString("X");            
            byte PosisjonsByte = byte.Parse(ServoPosHex, System.Globalization.NumberStyles.HexNumber);            
            string ServoNummerHex = ServoNummer.ToString("X");           
            byte ServoNummerByte = byte.Parse(ServoNummerHex, System.Globalization.NumberStyles.HexNumber);            
           port.Write(new byte[] { 0xFF, ServoNummerByte, PosisjonsByte }, 0, 3);            
            port.Close();

        }//MiniSSC
    }//servoklasse
}//namespace

I have searched many forums without result…can anyone clarify this for me please?

In Windows, I think a given serial port can only have one open SerialPort object at a time. Do you have multiple threads in this program? It’s possible that you tried to open the serial port in one thread, before the other thread has closed the port. This would result in an access denied error because the port is already open.

You should either use locking to avoid opening the serial port when it is already open, or store the SerialPort object permanently as a global variable so you don’t have to re-open it every single time you need to send some bytes on the port, or change your program so that there aren’t multiple threads trying to access the serial port at the same time.

Also, you didn’t ask for help on this part, but it pains me to see this part of the code that you wrote:

string ServoPosHex = ServoPos.ToString("X");
byte PosisjonsByte = byte.Parse(ServoPosHex, System.Globalization.NumberStyles.HexNumber);
string ServoNummerHex = ServoNummer.ToString("X");
byte ServoNummerByte = byte.Parse(ServoNummerHex, System.Globalization.NumberStyles.HexNumber);
port.Write(new byte[] { 0xFF, ServoNummerByte, PosisjonsByte }, 0, 3); 

To convert an int to a byte, you should just cast it, like this:

port.Write(new byte[] { 0xFF, (byte)ServoNummer, (byte)ServoPos }, 0, 3); 

This should be much faster than using strings.

–David

Hi David

Thanx for quick and informative response!
I am very new to threading, but yes I am using it, apperently…! Because, this was one of the possible causes I worked around last night, as an error regarding "Multiple Cross threading illegal…"or something popped up several places. But I thought I had solved this problem, using Invoke and optimizing code in several place, since I was able to avoid using “Control.CheckForIllegalCrossThreadCalls = false;” and I got no new error messages regarding “Mult. Cross-Thread”…

1 Your comment makes me curious though…Do you mean to say that if:
-Thread 1 has called and is writing the serial port
-and thread 2 has just finished writing to port and then closes it (in a way that in any other similiar code, would result in a “Multiple Cross-threading…” error)
-this would only result in “Access denied to COM3”, and not: “Multiple cross-threading illegale”…?

2If this is what you mean then I am actually very happy, since that rewriting/optimizing my code with regards to threading was my final “conclusion” on working my way around this prob. I am sry I did not mention this in the first post.

3As to your last comment… thnx :wink:

4Also; can anyone (or you David) verify this:
“In Windows, I think a given serial port can only have one open SerialPort object at a time.”

—Pls verify (or not) 1 primarily when responding—

Eivind

I don’t fully understand what you are asking in item 1. Your question is confusing because the events are not listed in chronological order. Also, I’m not familiar with an error called “Multiple cross-threading illegale” so if you want more details you should tell me the full .NET class name of the exception, and the full error message if you have it. You’re not likely to get a thread-related error in your SerialPort code, because you aren’t sharing any managed objects between threads (i.e. you create a new SerialPort object every time, and never share it).

You can easily verify 4 yourself. Just write some simple code that makes two SerialPort objects with the same PortName and see what happens when you try to open both of them. I know for sure that you can’t have two different applications accessing the same serial port at once, so it seems likely that you can’t have two SerialPort objects doing it either.

–David

Is this what you meant David?

1This is what pops up as the error:
InvalidOperationException was unhandled by user code
Cross-thread operation not valid: Control ‘y_coordtextBox’ accessed from a thread other than the thread it was created on.

(A textbox i put on the form to update laser coordinates continously, the actual name I don’t remember, I just made this up to provoke the fault for this post)

2When I view the error detail it shows me this .NET class name:
SystemInvalidOperationException

So my question is:
What would normally be presented as an 1 (and 2) for “any other” thread related problem, now is presented as “An exception of type ‘System.UnauthorizedAccessException’ occurred in System.dll but was not handled in user code” “Additional information: Access to COM3 denied”?

And this is due to; Quote David:
“You’re not likely to get a thread-related error in your SerialPort code, because you aren’t sharing any managed objects between threads (i.e. you create a new SerialPort object every time, and never share it).”

I am sorry if my questions seems easy/lazy, but I started learning C# and Aforge 3 months ago. Also this problem has really twisted my head, and I am having difficulties finding the correct solution for it.

Eivind

Yes. You’re basically correct, but you’re probably wrong that “any other” thread related problem will cause a SystemInvalidOperationException. There might be other thread-related problems which neither of us have seen yet, which raise a different kind of exception or no exception at all.

I’m sorry you’re still having trouble. I gave you three different strategies to try in my first post:

“You should either use locking to avoid opening the serial port when it is already open, or store the SerialPort object permanently as a global variable so you don’t have to re-open it every single time you need to send some bytes on the port, or change your program so that there aren’t multiple threads trying to access the serial port at the same time.”

I don’t know enough about your program to tell you which strategy is best, but I can help explain any of these strategies if you want.

–David

Long story short…I got it all working now! =)

Regarding the problem we discussed: Making the SerialPort object a permanent global one, and never close it (as long as the app is running) did solve this particular problem. Still i encountered other problems afterwards, and as I was writing a new question here last night…I decided to give them another try, and managed to solve them. Those challenges that remain are not “suited” on this forum, I think, since it is related to C# programming. (Even though I have got more accurate help here, than on any other forum I visited looking for help with C#)

Nevertheless I want to thank you David, for giving me quick and informative answers, and the necessary guidelines, even though you actually haven’t seen any of the code I have written! =) (I have excluded the servoclass from the project) That’s great!

Best regards
Eivind
Norway