winforms:从serialport读取并打印实时数据。许多错误/错误

winforms:从serialport读取并打印实时数据。许多错误/错误,winforms,visual-c++,charts,serial-port,ftdi,Winforms,Visual C++,Charts,Serial Port,Ftdi,我试图从MCU获取数据,将它们保存到一个文件并绘制它们。代码正常运行一段时间,然后随机挂起(有时在1秒后,有时在1分钟后…!)。此外,串行端口超时也不受尊重,即我没有收到任何超时异常。我用的是FTDI232RL芯片。我得到超时异常的唯一时间是在程序运行时拔下它 代码: private:System::Void START\u单击(系统::对象^sender,系统::事件参数^e){ 秒=0; 分钟=0; 小时=0; 天数=0; t=0; 如果((this->comboBox4->Text==St

我试图从MCU获取数据,将它们保存到一个文件并绘制它们。代码正常运行一段时间,然后随机挂起(有时在1秒后,有时在1分钟后…!)。此外,串行端口超时也不受尊重,即我没有收到任何超时异常。我用的是FTDI232RL芯片。我得到超时异常的唯一时间是在程序运行时拔下它

代码:

private:System::Void START\u单击(系统::对象^sender,系统::事件参数^e){
秒=0;
分钟=0;
小时=0;
天数=0;
t=0;
如果((this->comboBox4->Text==String::Empty)| |(this->textBox2->Text==String::Empty)| |(this->textBox3->Text==String::Empty)){
此->textBox1->Text=“请选择端口,保存文件目录和日志间隔”;
timer1->Enabled=false;
}
else{//开始分配
w=Convert::ToDouble(此->文本框3->文本);
双q=fmod(w*1000,10);
如果(q!=0){
MessageBox::Show(“日志记录间隔必须是0.01s的倍数”);
}
否则{
周期=静态(w*1000);
此->间隔->间隔=期间;
请尝试{//首先确保端口不忙/未打开
如果(!this->serialPort1->IsOpen){
//选择名称在comboBox4中的端口(选择端口)
this->serialPort1->PortName=this->comboBox4->Text;
//开埠
此->串行端口1->打开();
此->串行端口1->读取超时=周期+1;
此->串行端口1->WriteTimeout=period+1;
字符串^name=此->串行端口1->端口名;
开始=新字符串(“S”);
此->textBox1->Text=“日志记录已启动”;
timer1->Enabled=true;
间隔->启用=真;
myStream=newofstream(目录,ios::out);
*myStreamSeries[“ADC2”]->Points->Clear();
图表1->系列[“ADC3”]->点->清除();
图表1->系列[“ADC4”]->点->清除();
图表1->系列[“ADC5”]->点->清除();
图表1->系列[“ADC6”]->点->清除();
图表1->系列[“ADC7”]->点->清除();
图表1->系列[“ADC8”]->点->清除();
backgroundWorker1->RunWorkerAsync();
}
其他的
{
此->textBox1->Text=“警告:端口正忙或未打开”;
timer1->Enabled=false;
间隔->启用=错误;
}
}
捕获(未经授权的访问异常^)
{
此->textBox1->Text=“未经授权的访问”;
timer1->Enabled=false;
间隔->启用=错误;
}
}
}
}
private:System::Void backgroundWorker1\u DoWork(System::Object^sender,System::ComponentModel::DoWorkEventArgs^e){
而(!backgroundWorker1->CancellationPending){
如果(backgroundWorker1->CancellationPending){
e->Cancel=true;
返回;
}
t+=周期;
如果(tchart1->ChartAreas[“ChartArea1”]->AxisX->Minimum=0;
此->图表1->图表区域[“图表区域1”]->AxisX->最大值=t+10*周期;
}
否则{
此->图表1->图表区域[“图表区域1”]->AxisX->最小值=t-10*周期;
此->图表1->图表区域[“图表区域1”]->AxisX->最大值=t+10*周期;
}
*mystreamadxy(t,ADC[2]);
图表1->系列[“ADC4”]->点->添加XY(t,ADC[3]);
图表1->系列[“ADC5”]->点->添加XY(t,ADC[4]);
图表1->系列[“ADC6”]->点->添加XY(t,ADC[5]);
图表1->系列[“ADC7”]->点->添加XY(t,ADC[6]);
图表1->系列[“ADC8”]->点->添加XY(t,ADC[7]);
}
允许用户以秒为单位定义数据采集间隔(在代码中,此间隔在转换为双精度后为w)。在这种情况下,程序向MCU发送一个脉冲,请求新的数据传输。到目前为止,我已经测试了1秒的间隔(注意,在每个间隔期间,MCU发送8帧,每个帧代表一个ADC)。但是,我需要让它在某个点上以10毫秒的间隔运行。这可能吗?关于如何解决我在开始时提到的几个问题,有什么想法吗

提前谢谢

更新

只是想让你知道发生了什么: 我对图表部分进行了注释,并以1s的读取间隔运行了大约5分钟的程序。因此,我希望在输出文件中得到大约5x60=300个值,但我只得到了39个值(即从1s开始到39s)。程序仍在运行,但数据不再存储。 测试是在发布模式而不是调试模式下完成的。在调试模式下,在serialport->read下设置断点
private: System::Void START_Click(System::Object^  sender, System::EventArgs^  e) {
                 seconds=0;
                 minutes=0;
                 hours=0;
                 days=0;
                 t=0;


                 if((this->comboBox4->Text == String::Empty)||(this->textBox2->Text == String::Empty)||(this->textBox3->Text == String::Empty)){
                     this->textBox1->Text="please select port, save file directory and logging interval";
                     timer1->Enabled=false;

                 }





                 else{ // start assigning

                     w=Convert::ToDouble(this->textBox3->Text);
                     double q=fmod(w*1000,10);
                     if(q!=0){
                         MessageBox::Show("The logging interval must be a multiple of 0.01s");
                     }
                     else{
                         period=static_cast<int>(w*1000);
                         this->interval->Interval = period;
                         try{ // first make sure port isn't busy/open
                             if(!this->serialPort1->IsOpen){
                                 // select the port whose name is in comboBox4 (select port)
                                 this->serialPort1->PortName=this->comboBox4->Text;


                                 //open the port
                                 this->serialPort1->Open();


                                 this->serialPort1->ReadTimeout = period+1;
                                 this->serialPort1->WriteTimeout = period+1;

                                 String^ name_ = this->serialPort1->PortName;
                                 START=gcnew String("S");

                                 this->textBox1->Text="Logging started";
                                 timer1->Enabled=true;
                                 interval->Enabled=true;

                                 myStream=new ofstream(directory,ios::out);
                                 *myStream<<"time(ms);ADC1;ADC2;ADC3;ADC4;ADC5;ADC6;ADC7;ADC8;";
                                 *myStream<<endl;
                                 chart1->Series["ADC1"]->Points->Clear();
                                 chart1->Series["ADC2"]->Points->Clear();
                                 chart1->Series["ADC3"]->Points->Clear();
                                 chart1->Series["ADC4"]->Points->Clear();
                                 chart1->Series["ADC5"]->Points->Clear();
                                 chart1->Series["ADC6"]->Points->Clear();
                                 chart1->Series["ADC7"]->Points->Clear();
                                 chart1->Series["ADC8"]->Points->Clear();

                                 backgroundWorker1->RunWorkerAsync();

                             }
                             else
                             {
                                 this->textBox1->Text="Warning: port is busy or isn't open";
                                 timer1->Enabled=false;
                                 interval->Enabled=false;
                             }
                         }
                         catch(UnauthorizedAccessException^)
                         {
                             this->textBox1->Text="Unauthorized access";
                             timer1->Enabled=false;
                             interval->Enabled=false;
                         }
                     }

                 }
             }



private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) {

                 while(!backgroundWorker1->CancellationPending){
                     if(backgroundWorker1->CancellationPending){
                         e->Cancel=true;
                         return;
                     }
                     t+=period;
                     if(t<10*period){
                         this->chart1->ChartAreas["ChartArea1"]->AxisX->Minimum=0;
                         this->chart1->ChartAreas["ChartArea1"]->AxisX->Maximum=t+10*period;
                     }
                     else {
                         this->chart1->ChartAreas["ChartArea1"]->AxisX->Minimum=t-10*period;
                         this->chart1->ChartAreas["ChartArea1"]->AxisX->Maximum=t+10*period;
                     }
                     *myStream<<t<<";";


                     for (int n=0;n<8;n++){
                         adc_array[n]= this->serialPort1->ReadByte();

                     }

                     Array::Copy(adc_array,ADC,8);

                     for(int f=0; f<8; f++){
                         *myStream<<ADC[f]<<";";
                     }

                     *myStream<<endl;

                     backgroundWorker1->ReportProgress(t);

                 }
             }


private: System::Void backgroundWorker1_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e) {
                 chart1->Series["ADC1"]->Points->AddXY(t,ADC[0]);
                 chart1->Series["ADC2"]->Points->AddXY(t,ADC[1]);
                 chart1->Series["ADC3"]->Points->AddXY(t,ADC[2]);
                 chart1->Series["ADC4"]->Points->AddXY(t,ADC[3]);
                 chart1->Series["ADC5"]->Points->AddXY(t,ADC[4]);
                 chart1->Series["ADC6"]->Points->AddXY(t,ADC[5]);
                 chart1->Series["ADC7"]->Points->AddXY(t,ADC[6]);
                 chart1->Series["ADC8"]->Points->AddXY(t,ADC[7]);
         }