【问题标题】:COM port becomes busy at seemingly random timesCOM 端口在看似随机的时间变得忙碌
【发布时间】:2019-08-11 15:08:33
【问题描述】:

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

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

首先,串口类。这是在每个轨迹栏的 Scroll 事件上运行的:

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);
        }
    }
}

【问题讨论】:

  • 使用同步 Serial.read() 会导致读取不均匀。最好使用异步方法。同步读取被机器上的其他进程阻塞,而异步读取使用在其他进程运行时不会被阻塞的事件。
  • 是否有异步 Serial.read() 等效项?我很难找到一个
  • 查看以下 msdn 页面事件 DataReceived : docs.microsoft.com/en-us/dotnet/api/…
  • 我很困惑。那么我的 Arduino 代码可以吗,但是我的串行端口类是问题所在?或者是周围的其他方式?另外,如果我将数据发送到我的 C# 程序,DataRecieved 事件是否适用,或者我应该将 DataRecieved 事件添加到我的专业微代码中?
  • 两者都不是。您的机器是多处理器并与您的代码并行运行其他进程。由于其他应用程序正在运行,您正在接收数据而不是处理。因此,您会在接收缓冲区中积压,从而创建随机时间。使用 Async (Events) 可以让您的应用更均匀地处理接收到的数据。

标签: c# arduino serial-port led


【解决方案1】:

我研究了库提供的 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;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    相关资源
    最近更新 更多