0

I have a microcontroller hooked up via USB CDC/ACM to the PC. When I try to open the port with an app I'm trying to make that uses SerialPort, I see nothing on the microcontroller. I can easily set break points in the micro and watch the port open/write/read/close events get triggered when using RealTerm, TeraTerm, PuTTy, etc, but for my application, nothing. No error is given and the application seems to think that everything worked fine. After opening, even though I see nothing on the micro, the other terminal applications can no longer connect on that port, but once I close it in my app, they work again. Further, if I try to write to the port after opening, the app just hangs. So what step am I missing?

Here is my code:

using System;
using System.ComponentModel;
using System.IO.Ports;
using System.Windows;
using System.Windows.Controls;

namespace SerialApp
{
    public partial class MainWindow : Window
    {
        static SerialPort _serialPort = new SerialPort();
        static byte[] read_buffer = new byte[4096];
        static byte[] getSerialNumberCmd = { 0x6D, 0x69, 0x6E, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

        public MainWindow()
        {
            InitializeComponent();
        }

        private void comboBoxPorts_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string port = comboBoxPorts.SelectedIndex.ToString();
            port = "COM" + port;

            _serialPort.PortName = port;
            _serialPort.BaudRate = 115200;
            _serialPort.Parity = Parity.None;
            _serialPort.DataBits = 8;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.ReadBufferSize = 4096;
            _serialPort.WriteTimeout = 500;
            _serialPort.ReadTimeout = 500;
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_serialPort.IsOpen) _serialPort.Close();
                if (_serialPort != null)
                {
                    _serialPort.Open();
                    _serialPort.DataReceived += Serial_DataReceived;

                    comboBoxPorts.IsEnabled = false;
                    buttonClosePort.IsEnabled = true;
                    buttonOpenPort.IsEnabled = false;
                    label1.Content = "Connected to " + _serialPort.PortName;
                }
                else
                {
                    label1.Content = "Choose a COM port.";
                }
            }
            catch(Exception ex)
            {
                label1.Content = "Invalid COM port.";
            }
        }

        private void Serial_DataReceived(object s, SerialDataReceivedEventArgs e)
        {
            _serialPort.Read(read_buffer, 0, 64 + 12);
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if (_serialPort.IsOpen)
            {
                _serialPort.Close();
            }
            if (_serialPort != null)
            {
                _serialPort.Dispose();
            }
        }

        private void buttonClosePort_Click(object sender, RoutedEventArgs e)
        {
            if (_serialPort.IsOpen)
            {
                _serialPort.Close();
                
                buttonClosePort.IsEnabled = false;
                buttonOpenPort.IsEnabled = true;
                comboBoxPorts.IsEnabled = true;
                label1.Content = "Choose a COM port.";
            }
        }

        private void buttonGetSerial_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_serialPort.IsOpen)
                {
                    _serialPort.Write(getSerialNumberCmd, 0, 64);
                }
            }
            catch(Exception ex)
            {
                _serialPort.Close();
                labelSerialNumber.Content = ex.Message;
            }
        }
    }
}

Incidentally I tried to do the same thing on another microcontroller of a completely different family and I see the same behavior.

TrivialCase
  • 1,060
  • 2
  • 14
  • 27

1 Answers1

1

Try adding the following:

_serialPort.DtrEnable = true; //enable Data Terminal Ready
_serialPort.RtsEnable = true; //enable Request to send

See this post for a complete code example. The post was written for Windows Forms, but you should be able to use a majority of the code for your situation as well.

Tu deschizi eu inchid
  • 4,117
  • 3
  • 13
  • 24
  • Oh dear sweet merciful @user9938 thank you! This was very literally driving me nuts. I haven't seen that used elsewhere. – TrivialCase Mar 17 '21 at 12:52