COM 端口在看似随机的时间变得繁忙

COM port becomes busy at seemingly random times

我正在制作一个将 LED 照明指令发送到 sparkfun pro micro 的 c# 程序。它通常在一开始工作,但有可能在更改其中一个颜色滑块时失败,导致 com 端口繁忙且无法使用,直到我断开 pro micro 并将其代码重新上传到它

我试图在我的 catch 语句中关闭端口,但它似乎根本没有帮助(我认为实际上让事情变得更糟)。我不确定是我的串行端口 class 有问题还是 pro 微代码有问题所以我会 post 两个

首先是串口class。这是每个轨迹栏的滚动事件上的 运行:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms;
using System.Diagnostics;

namespace LED_Controller
{
    public class SerialPortsAccess
    {
        public string testString;

        private SerialPort port;// = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);

        [STAThread]
        static void createNew(string[] args)
        {
            //new SerialPortsAccess("COM3");
        }

        public SerialPortsAccess(string COM)
        {
            string[] lastInfo = System.IO.File.ReadAllLines(@"C:\Users\Alex\source\repos\LED Controler\LED Controler\Last.txt");
            string stringout = "";
            port = new SerialPort(COM, 9600, Parity.None, 8, StopBits.One);
            try
            {
                port.Open();

                for (int i = 0; i < lastInfo.Length; i++)
                {
                    //port.WriteLine(lastInfo[i]);
                    stringout += lastInfo[i];
                    if ((i + 1) < lastInfo.Length)
                    {
                        stringout += '|';
                    }
                }

                stringout += '\n';
                port.Write(stringout);
                Debug.WriteLine(stringout);
                port.Close();
            }
            catch
            {
                //try
                //{
                    //port.Close();
                //}
                //catch
                //{

                //}
                Debug.WriteLine("NO DEVICE FOUND");
            }
        }
    }
}

这是我的 arduino 代码。它很长,但是 getData() 函数的大部分都对每个变量重复相同的过程(我是新手所以我的技术可能很糟糕):

#include <SPI.h>
#include <Adafruit_DotStar.h>

#define NUMPIXELS 60

Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R;
int G;
int B;
int Bright;

int readLine(int readch, char * buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0)
  {
    switch(readch)
    {
      case '\r':
      {
        break;
      }
      case '\n':
      {
        rpos = pos;
        pos = 0;
        return rpos;
      }
      default:
      {
        if (pos < len-1) 
        {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
      }
  }

  return 0;
}
}

void loop() {
  getData();


  if (mode == 1)
  {
    for (int i = 0; i < NUMPIXELS; i++)
    {
      strip.setPixelColor(i, G, R, B);
    }
    strip.setBrightness(Bright);
    strip.show();
  }
  else
  {
    strip.setPixelColor(0, 255, 255, 255);
    strip.setBrightness(25);
    strip.show();
  }
}

void getData()    // this function has a do while loop for each variable. Sorry if this is bad form
{
  char buf[80];
  bool redo = true;

  if(readLine(Serial.read(), buf, 80) > 0)
  {
    int i = 0;
    int j = 0;
    bool skip = false;
    char fin[3];
    if (skip == false)
    {
    do//                                mode
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          mode = atoi(fin);
          //Serial.print(mode);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do//                     number of colors
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          numColors = atoi(fin);
          //Serial.print(numColors);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do//                            
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          fadeSpeed = atoi(fin);
          //Serial.print(fadeSpeed);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          BBCC = atoi(fin);
          //Serial.print(BBCC);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          R = atoi(fin);
          //Serial.print(R);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          G = atoi(fin);
          //Serial.print(G);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          B = atoi(fin);
          //Serial.print(B);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          Bright = atoi(fin);
          //Serial.println(Bright);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }
  }
}

C# 代码应该在每次轨迹栏更改时将数据发送到表单一次,然后关闭端口,直到进行另一次更改。 pro micro 应该接收代码并解释它。但是,在此过程中的某个地方,连接已断开并且不会重新建立。这里出了什么问题?

编辑:我尝试使用数据接收事件,但现在端口甚至无法打开。因为访问被拒绝。我用错了吗?新的 C# 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms;
using System.Diagnostics;

namespace LED_Controller
{
    public class SerialPortsAccess
    {
        public string testString;
        bool fail = false;
        private SerialPort port;// = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);

        [STAThread]
        static void createNew(string[] args)
        {
            //new SerialPortsAccess("COM3");
        }

        public SerialPortsAccess(string COM)
        {
            port = new SerialPort(COM, 9600, Parity.None, 8, StopBits.One);

            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

            //try
            //{
                port.Open();
            //}
            //catch
            //{
                //Debug.WriteLine("ERROR OPENING PORT");
            //}
        }
        public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string[] lastInfo = System.IO.File.ReadAllLines(@"C:\Users\Alex\source\repos\LED Controler\LED Controler\Last.txt");
            string stringout = "";
            do
            {
                try
                {
                    //port.Open();

                    for (int i = 0; i < lastInfo.Length; i++)
                    {
                        //port.WriteLine(lastInfo[i]);
                        stringout += lastInfo[i];
                        if ((i + 1) < lastInfo.Length)
                        {
                            stringout += '|';
                        }
                    }

                    stringout += '\n';
                    port.Write(stringout);
                    Debug.WriteLine(stringout);
                    port.Close();
                }
                catch
                {
                    fail = true;
                    Debug.WriteLine("DEVICE LOST");
                    port.Close();
                }
            } while (fail == false);//port.BytesToRead != 0);
        }
    }
}

我研究了随库提供的 Adafruit dotstar 示例代码的示例代码,发现它可能是我在不刷新条带的情况下尝试 运行 的 LED 数量。当我将我的代码与示例混合时,我能够毫无问题地 运行 大约 30 个 LED。任何更多都会导致开发板进入故障模式并且 COM 端口将再次无法访问

这是新代码:

#include <Adafruit_DotStar.h>
#include <SPI.h>

#define NUMPIXELS 60
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R;
int G;
int B;
int Bright;

void setup() {

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif

  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP
}

// Runs 10 LEDs at a time along strip, cycling through red, green and blue.
// This requires about 200 mA for all the 'on' pixels + 1 mA per 'off' pixel.

int      head  = 0, tail = -10; // Index of first 'on' and 'off' pixels
uint32_t color = 0xFFFFFF;      // 'On' color (starts red)

void loop() {

  //strip.setPixelColor(head, color); // 'On' pixel at head
  //strip.setPixelColor(tail, 0);     // 'Off' pixel at tail
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  getData();

  if (mode == 1)
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, G, R, B);
    }
    strip.setBrightness(Bright);
    strip.show();
  }
  else
  {
    for (int i = 0; i < (60); i++)
    {
      if (i % 2 == 0)
        strip.setPixelColor(i, 150, 200, 40);
    }
    strip.setBrightness(255);
    strip.show();
  }
}

int readLine(int readch, char * buffer, int len)
{
  static int pos = 0;
  int rpos;

  if (readch > 0)
  {
    switch(readch)
    {
      case '\r':
      {
        break;
      }
      case '\n':
      {
        rpos = pos;
        pos = 0;
        return rpos;
      }
      default:
      {
        if (pos < len-1) 
        {
          buffer[pos++] = readch;
          buffer[pos] = 0;
        }
      }
  }

  return 0;
}
}

void getData()
{
  char buf[80];
  bool redo = true;

  if(readLine(Serial.read(), buf, 80) > 0)
  {
    int i = 0;
    int j = 0;
    bool skip = false;
    char fin[3];
    if (skip == false)
    {
    do//                                mode
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          mode = atoi(fin);
          //Serial.print(mode);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do//                     number of colors
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          numColors = atoi(fin);
          //Serial.print(numColors);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do//                            
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          fadeSpeed = atoi(fin);
          //Serial.print(fadeSpeed);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          BBCC = atoi(fin);
          //Serial.print(BBCC);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          R = atoi(fin);
          //Serial.print(R);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          G = atoi(fin);
          //Serial.print(G);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          skip = true;
          redo = false;
          break;
        }
        case '|':
        {
          B = atoi(fin);
          //Serial.print(B);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }



    if (skip == false)
    {
    do
    {
      switch (buf[i])
      {
        case '\n':
        {
          Bright = atoi(fin);
          //Serial.println(Bright);
          i++;
          redo = false;
          break;
        }
        default:
        {
          fin[j] = buf[i];
          i++;
          break;
        }
      }
      j++;
    }while(redo);
    redo = true;
    j = 0;
    }
  }
}