none
Unauthorized Exception for serial port RRS feed

  • Question

  • I am trying to access RFID Reader through Arduino application which gives me the right output on control monitor.

    But when I tried to access it through visual studio C#, it works only once and then gives me access is denied! And also stopped working on Arduino IDE.

    public products()
        {
            InitializeComponent();
            initializeRFIDPort();
        }
    //Function  to initialize the serial port
    
     SerialPort RFIDPort    
     public SerialPort initializeRFIDPort()
        {
    
            try
            {
                RFIDPort = new SerialPort("COM4",9600,Parity.None,8, StopBits.One);
              
                if (RFIDPort.IsOpen)
                    RFIDPort.Close();
    
                if(!RFIDPort.IsOpen)
                        RFIDPort.Open();
                }
            catch (UnauthorizedAccessException ex) {MessageBox.Show( ex.Message); }
            catch (Exception)
            {
                RFIDPort = null;
            }
    
            return RFIDPort;
        }
     private void ScanButton_Click(object sender, EventArgs e)
        {
            try
            {
    
                scanButtonIsClicked = true;
                if (RFIDPort.IsOpen)
                {
                    RFIDPort.DataReceived += serialPort1_DataReceived;
                    textBox1.Text = "";
    
                }
                else
                    MessageBox.Show("RFID Reader is not connected!");
            }
            catch (IOException) { MessageBox.Show("Please reconnect your device "); }
            catch (System.Exception)
            {
                MessageBox.Show("Please Try Again");
            }
         }
    
      private void Searchbutton_Click(object sender, EventArgs e)
        {
            scansearchbtn = true;
            scanButtonIsClicked = false;
    
            try
            {
                if (RFIDPort.IsOpen)
                {
                     RFIDPort.DataReceived += serialPort1_DataReceived;
    
                    textBox2.Text = "";
    
                }
                else { MessageBox.Show("RFID Reader is not connected!"); }
            }
            catch (IOException) { MessageBox.Show("Please reconnect your device ");}
            }
    
    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
    
                string line = RFIDPort.ReadLine();
    
                if (scanButtonIsClicked == true)
                    this.BeginInvoke(new LineReceivedEvent(LineReceived), line);
                else
                    this.BeginInvoke(new LineReceivedEvent(Line2Received), line);
            }
            catch (Exception){ MessageBox.Show("Can't Read from RFID Device.Please try again"); }
    
        }
    
        private delegate void LineReceivedEvent(string line);
    
        private void LineReceived(string line)
        {
            textBox2.Text = line;
    
        }
        private void Line2Received(string line)
        {
            textBox1.Text = line;
    
        }

    Then I close the serial port in the main forum 

    //The main forum is a group of user control,products1:UserControl 
    
    private void StockMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                Application.Exit();
    			if (products1.RFIDPort.IsOpen == true)
    				products1.RFIDPort.Close();
    		}

    sometimes when I close the program it gives me the exception that I/O is aborted, not al the time.

    Please, If anyone can help. Thanks in return.


    heba ayass

    Thursday, June 28, 2018 9:47 AM

Answers

  • Close, I think.

    public class MyForm : Form
    {
       protected override void OnLoad ( EventArgs e )
       {
          base.OnLoad(e);
     
          //Only do this outside the designer
          if (!DesignMode)
             RFIDPort = InitializeRFIDPort();
       }
    }
    
    private SerialPort InitializeRFIDPort ()
    {
       //Try catch serves no purpose here...
       var port = new SerialPort()
       {   
       };
    
       port.DataReceived += serialPort_DataReceived;
    
       return port;
    }
    
    
    private void serialPort_DataReceived ( object sender, EventArgs e )
    
    {
       var port = sender as SerialPort;
       try
       {
           var line = port.ReadExisting();
           LineReceived(line);
       } catch (Exception ex)
       {
          ...
       };
    }
    
    
    private void Scanbutton_Click ( object sender, EventArgs e )
    {
       try
       {
           ...
           if (!RFIDPortIsOpen)
              RFIDPort.Open();
       } catch (Exception ex)
       {
          ...
       };
    }
    
    


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by HEBA_AA Saturday, June 30, 2018 9:42 PM
    Friday, June 29, 2018 2:47 PM
    Moderator

All replies

  • I see a couple of potential issues with your code but I cannot say whether they are the issues you're having.

    It appears that products is a form. In that case you're initializing the port and opening it when the form is created, not when it is loaded. This includes when you load it up in the designer. Since the port is open when the form gets created and won't be closed unless the form is then displayed you are potentially leaking a port. The correct solution here is to open the port only when you're ready to use it (probably in each of your search and scan handlers). If you really need to open it earlier then do so in OnLoad which is called when the form loads. Ideally wrap this in a DesignMode check to make sure you don't have it run while inside the IDE.

    Another issue I see is that each time the button(s) are clicked you are hooking up yet another event handler to the data received. This is going to cause problems. Since you seem to be using the same handler for both calls then just set the handler up front (in the designer) and then remove that code. Following the earlier suggestion, your handlers should check to see if you're already using the port. If so then you should probably disable the button and do nothing. If not then open the port to start receiving input (or enable the port if you disabled it). You don't need to do anything else there.

    In your form close handler you're exiting the app before you close the port. Hence you have another leak. You don't need to call exit at all. Just close the port if it is open and return. If this is your main form then the app will automatically terminate. If it isn't then ensure the port is closed before you call exit.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, June 28, 2018 2:29 PM
    Moderator
  • "Ideally wrap this in a DesignMode check to make sure you don't have it run while inside the IDE."

    You mean by this that I have to create connect button in The DesignMode and the user should initialize it?

    "Since you seem to be using the same handler for both calls then just set the handler up front (in the designer) and then remove that code. Following the earlier suggestion, your handlers should check to see if you're already using the port. If so then you should probably disable the button and do nothing. If not then open the port to start receiving input (or enable the port if you disabled it). You don't need to do anything else there."

    You mean I shouldn't call data receiver event when user click on scan and search button, it will be called automatically when I open port? also if you can explain more about what I should be writing in the data receiver handler?  (sorry for my bad language)

    Thanks for your help : )



    • Edited by HEBA_AA Friday, June 29, 2018 9:37 AM
    Friday, June 29, 2018 9:36 AM
  • I have tried to edit it like this, If u please check it to me to know if I am doing it right

    public SerialPort initializeRFIDPort()
    		{
    
    			try
    			{
    				if (RFIDPort != null && RFIDPort.IsOpen)
    					RFIDPort.Close();
    				RFIDPort = new SerialPort();
    				RFIDPort.PortName = "COM4";
    				RFIDPort.BaudRate = 9600;
    				RFIDPort.Parity = Parity.None;
    				RFIDPort.DataBits = 8;
    				RFIDPort.StopBits = StopBits.One;
    				RFIDPort.Handshake = Handshake.None;
    				RFIDPort.RtsEnable = true;
    
    				//create our Data Received Event
    				RFIDPort.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);		
    				}
    			catch (Exception)
    			{
    				RFIDPort = null;
    			}
    			return RFIDPort;
    		}
    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    		{
    			try
    			{
    				SerialPort sp = (SerialPort)sender;
    				string line = sp.ReadExisting();
    				LineReceived(line);
    
    			}
    			catch (Exception){ MessageBox.Show("Can't Read data"); }
    			
    		}
    
    		private delegate void LineReceivedEvent(string line);
    
    		private void LineReceived(string line)
    		{
    			if (InvokeRequired)
    				Invoke(new LineReceivedEvent(LineReceived), line);
    			else
    			{ if (scanButtonIsClicked == true)
    					textBox2.Text = line;
    				else textBox1.Text = line;
    			}
    		}
    
    private void Scanbutton_Click(object sender, EventArgs e)
    		{
    			try
    			{
    				scanButtonIsClicked = true;
    				textBox1.Text = "";
    				textBox2.Text = "";
                    initializeRFIDPort();
    				RFIDPort.Open();
    				if(!RFIDPort.IsOpen)
    					MessageBox.Show("RFID device is not connected ");
    			}
    			catch (System.Exception)
    			{
    				MessageBox.Show("Please Try Again");
    			}
    		}
    private void button1_Click(object sender, EventArgs e)
    		{
    			try
    			{
    				textBox2.Text = "";
    				textBox1.Text = "";
    				initializeRFIDPort();
    				RFIDPort.Open();
    				if(!RFIDPort.IsOpen)
    					MessageBox.Show("RFID is not connected");
    			}
    			
    			catch (Exception)
    			{
    				MessageBox.Show("Please Try again");
    			}
    			
    		}

    Thank u in advance


    heba ayass

    Friday, June 29, 2018 12:00 PM
  • Close, I think.

    public class MyForm : Form
    {
       protected override void OnLoad ( EventArgs e )
       {
          base.OnLoad(e);
     
          //Only do this outside the designer
          if (!DesignMode)
             RFIDPort = InitializeRFIDPort();
       }
    }
    
    private SerialPort InitializeRFIDPort ()
    {
       //Try catch serves no purpose here...
       var port = new SerialPort()
       {   
       };
    
       port.DataReceived += serialPort_DataReceived;
    
       return port;
    }
    
    
    private void serialPort_DataReceived ( object sender, EventArgs e )
    
    {
       var port = sender as SerialPort;
       try
       {
           var line = port.ReadExisting();
           LineReceived(line);
       } catch (Exception ex)
       {
          ...
       };
    }
    
    
    private void Scanbutton_Click ( object sender, EventArgs e )
    {
       try
       {
           ...
           if (!RFIDPortIsOpen)
              RFIDPort.Open();
       } catch (Exception ex)
       {
          ...
       };
    }
    
    


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by HEBA_AA Saturday, June 30, 2018 9:42 PM
    Friday, June 29, 2018 2:47 PM
    Moderator
  • Thank you u are awesome:) now it stars reading from Arduino.

    one more thing my in my Arduino code I have initialized the tag by hex key and in my program it first scans FF FF FF FF, I tried to remove it from setup it stops working, any suggestion to show directly my scanned id

    #include <SPI.h>
    #include <MFRC522.h>
    
    #define SS_PIN 10
    #define RST_PIN 9
     
    MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
    
    MFRC522::MIFARE_Key key; 
    
    // Init array that will store new NUID 
    byte nuidPICC[10];
    
    void setup() 
    { 
      Serial.begin(9600);
      SPI.begin(); // Init SPI bus
      rfid.PCD_Init(); // Init MFRC522 
      for (byte i = 0; i < 6; i++) 
      {
        key.keyByte[i] = 0xFF;
      }
      printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
      Serial.println();
    }
     
    void loop() 
    {
    
      if ( ! rfid.PICC_IsNewCardPresent())
        return;
      if ( ! rfid.PICC_ReadCardSerial())
        return;
    
        //  Serial.print(F("PICC type: "));
       MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
       //  Serial.println(rfid.PICC_GetTypeName(piccType));
    
      // Check is the PICC of Classic MIFARE type
      if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K) 
          {
            Serial.println(F("Your tag is not of type MIFARE Classic."));
            return;
          }
        // Store NUID into nuidPICC array
        for (byte i = 0; i < 4; i++) 
        {
          nuidPICC[i] = rfid.uid.uidByte[i];
        }
       
        printHex(rfid.uid.uidByte, rfid.uid.size);
        Serial.println();
      // Halt PICC
      rfid.PICC_HaltA();
    
      // Stop encryption on PCD
      rfid.PCD_StopCrypto1();
    }
    
    
    void printHex(byte *buffer, byte bufferSize)
    {
      for (byte i = 0; i < bufferSize; i++) {
        Serial.print(buffer[i] < 0x10 ? " 0" : " ");
        Serial.print(buffer[i], HEX);
      }
    }



    • Edited by HEBA_AA Friday, June 29, 2018 9:36 PM
    Friday, June 29, 2018 9:36 PM
  • "any suggestion to show directly my scanned id"

    I'm afraid I don't understand what you're trying to show directly and where. If this is related to the C++ code you posted then you should probably post over in the Arduino forums. We only provide C# support in this forum.


    Michael Taylor http://www.michaeltaylorp3.net

    Saturday, June 30, 2018 4:29 AM
    Moderator
  • OK thank u :) 

    about my c# code if I want to scan tags in more than one class. Do I use the same concept for all classes? or will the port be blocked?


    heba ayass

    Saturday, June 30, 2018 7:27 AM
  • Serial ports are shared resources so if you want to use the same port in multiple areas of your code you're going to have to share the instance. If you're going to do that then you need to worry about threading issues. It'll get more complicated. Alternatively you can have a single thread using the port and then queue requests to the port from other threads. This resolves the threading issue mostly but would limit some aspects of what you can do. 

    Michael Taylor http://www.michaeltaylorp3.net

    Saturday, June 30, 2018 6:24 PM
    Moderator
  • Ok, I prefer testing it in one class. thank u for your time I appreciate it : )

    heba ayass

    Saturday, June 30, 2018 9:42 PM