我試圖從MCU獲取數據,將它們保存到文件並繪製它們。該代碼正常運行一段時間,然後隨機掛起(有時在1秒後,有時在1分鐘後!)。此外,serialport超時不受尊重,即我沒有收到任何超時異常。我正在使用FTDI232RL芯片。唯一一次出現超時異常的情況是,我在程序運行時拔下它。winforms:從串口讀取並繪製實時數據。許多錯誤/錯誤
代碼:
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]);
}
則允許用戶在用於數據採集秒,以限定的時間間隔(在此代碼間隔爲w後轉換爲雙)。在這種情況下,程序向MCU發送一個脈衝請求新的數據傳輸。到目前爲止,我一直在測試這個間隔1秒(注意,在每個間隔期間,MCU發送8幀,每個幀代表一個ADC)。但是,我需要在某個時間點運行10ms的時間間隔。這可能嗎?關於如何解決我在開頭提到的幾個問題的任何想法?
在此先感謝
UPDATE
只給你發生了什麼事的想法: 我評論的圖表部分和運行程序約5分鐘,以1秒的讀取時間間隔。所以我期望在輸出文件中得到5x60 = 300的值,但我只有39(即從1s開始到39s)。該程序仍在運行,但數據不再被存儲。 測試是在發佈模式而不是調試模式下完成的。在調試模式下,在serialport-> readbyte()下設置一個斷點,不會重現問題。我的猜測是這是程序和MCU之間的時間問題。
謝謝你的回覆Hans。從我的理解,我需要做到以下幾點:1)改變軸的最小和最大值必須在主線程內完成 2)reportprogress(adc_array)而不是t 3)圖表不能刷新那麼快,所以我將執行以下操作:將每個10x8數據存儲在一個臨時數組中(讓它稱爲temp),然後繪製它們。其實我相信reportprogress(temp)會更好,不是嗎? – 2013-02-13 16:06:45