请问各位,如果使用此种方法能否将串口中读取出的数据实时绘制出来(不丢数)?刚实习就遇上这么个难题,小弟表示压力很大、、、、、、、有老各位给小弟讲讲实现思路,或者给小弟发个demo,小弟邮箱[email protected]小弟在此谢过了

解决方案 »

  1.   

    这个不难,串口通讯资料很多,读取数据不难,读取到的数据用picturebox创建Graphics对象,然后上面画上x(时间),y(数据)轴,把数据用Graphics里面的DrawLines画上就可以了。读取到的数据变成Point保存到数组,在DrawLines中可以指定数组,直接就画出来了。
      

  2.   

    将数据保存到内存,然后搞个线程从内存中读取数据,根据你画图区域的长宽和实际数据折算成一个坐标,然后就在OnPaint事件中画就是了
      

  3.   

    设置个Timer每通过3秒发送读取数据指令,在串口接收数据事件中接收数据并绘制出来即可
      

  4.   

    串口读数据   可以用串口自带的DataReceived事件
    bytes[] bb=port1.Read(bb,0,port1.BytesToRead);
    也可以写死循环   过一段时间
    string xxx=port1.ReadLine();
    totalBuffer+=xxx;
    string xxx=prot1.ReadExisting();等等
    很多方法都可以读的  关键看你串口进来的数据是什么样子
    读完以后  存起来 放在画面上 就哦了
      

  5.   

    我刚刚发现vs自带了一个mychart控件和serilport控件,请问如果使用这两个控件可以满足我的条件么?之前没接触过这些,所以现在还是一头雾水中
      

  6.   

    读串口数据可以用serilport对象的,mychart没有用过,如果有用过的可以解答一下,但是用picturebox肯定是可以的。你可以写个线程,一直监听串口,有数据的话你就解析出来,你读到的数据肯定都是ascii码,你需要根据你实际接收协议的格式处理后得到实时数据的value,这需要你自己分析了。给个建议,为了展示方便,你可以把曲线部分做成一个组件,其它程序调用的时候只需要传递坐标轴的value就行了,这样省事。  楼上的哪位写到的port1应该就是serilport对象,你可以从网上搜个例子,一堆一堆的,呵呵
    ---------------------------------------------------------------
    可以用串口自带的DataReceived事件
    bytes[] bb=port1.Read(bb,0,port1.BytesToRead);
    也可以写死循环 过一段时间
    string xxx=port1.ReadLine();
    totalBuffer+=xxx;
    string xxx=prot1.ReadExisting();等等
    很多方法都可以读的 关键看你串口进来的数据是什么样子
    读完以后 存起来 放在画面上 就哦了
      

  7.   

    各位大哥大姐,能否给小弟发个demo,线程还有绘图和串口通信这块以前从未接触过,经理只给了一个vb的源程序,看不懂啊,很茫然小弟邮箱[email protected]
      

  8.   

    我用gdi+做个了实时曲线的demo,请问程序运行后为什么会出现闪烁的情况?
      

  9.   

    求各位大哥大姐给小弟翻一下下边的这两段vb源代码啊看不懂鸟(主要想知道原程序的通信协议和曲线图相关变量的计算表达式)Public gDiameter(55) As Single  '粒径数组
    Public gDataInDiamete(55) As Long '每次从串口读取的粒径通道的数据(52个粒径通道)
    Public gChannelData(65) As Long   '从串口读取的强度通道数据(64个强度通道)'CRC-16校验函数,参数待校验的数组,返回值 余数
    Function CRC16(data() As Byte) As String
        Dim CRC16Lo As Byte, CRC16Hi As Byte        'CRC寄存器
        Dim CL As Byte, CH As Byte                  '多项式码 & H8001
        Dim SaveHi As Byte, SaveLo  As Byte
        Dim i As Integer
        Dim Flag As Integer
        CRC16Lo = &HFF
        CRC16Hi = &HFF
        CL = &H1
        CH = &H80
        For i = 0 To UBound(data)
            CRC16Lo = CRC16Lo Xor data(i)           '每一个数据与CRC寄存器进行异或
            For Flag = 0 To 7
                SaveHi = CRC16Hi
                SaveLo = CRC16Lo
                CRC16Hi = CRC16Hi \ 2                    '高位右移一位
                CRC16Lo = CRC16Lo \ 2                    '低位右移一位
                If ((SaveHi And &H1) = &H1) Then               '如果高位字节最后一位为1
                    CRC16Lo = CRC16Lo Or &H80              '则低位字节右移后前面补1
                End If                               '否则自动补0
                If ((SaveLo And &H1) = &H1) Then               '如果LSB为1,则与多项式码进行异或
                    CRC16Hi = CRC16Hi Xor CH
                    CRC16Lo = CRC16Lo Xor CL
                End If
            Next Flag
        Next i
        Dim ReturnData(1)     As Byte
        ReturnData(0) = CRC16Hi                  'CRC高位
        ReturnData(1) = CRC16Lo                  'CRC低位
        CRC16 = ReturnData
    End Function'处理串口数据
    Private Sub MSComm1_OnComm()
        'Dim rs_sChannelData(55) As Long
        'Dim rs_sIntensityData(52, 64) As Long
        'Dim rs_pIntensity(65) As Long
        Dim vbReceive As Variant
        Dim i, j As Integer
        Dim L As Integer
        Dim dSum As Long
        Dim pm25t As Single
        Dim pm10t As Single
        pm25t = 0
        pm10t = 0
            
        If MSComm1.CommEvent = comEvReceive Then
            'wait (50)                    'Receive the rs232 chars
            
            If MSComm1.InBufferCount >= 6764 Then
                vbReceive = ((MSComm1.Input))
                If ((vbReceive(0) = 255) And (vbReceive(1) = 1)) Then
                
            '        //接下来是52个粒径通道的生物粒子浓度
                    dSum = 0
                    
                    gDataInDiamete(1) = -1
                    gDataInDiamete(2) = -1
                    gDataInDiamete(3) = -1
                    gDataInDiamete(4) = (vbReceive(2 + 2 * 52 * 64) * 256 + vbReceive(2 + 2 * 52 * 64 + 1))  ' + Int(800 * Rnd + 1)
                    
                    dSum = dSum + gDataInDiamete(4)
                    
                    For i = 1 To 51
                        gDataInDiamete(i + 4) = vbReceive(2 + 2 * 52 * 64 + 2 * i) * 256 + vbReceive(2 + 2 * 52 * 64 + 2 * i + 1) ' + Int(800 * Rnd + 1)
                        dSum = dSum + gDataInDiamete(i + 4)
                                          
                       Next i
                       
                     For i = 0 To 22
                        
                        pm25t = pm25t + gDataInDiamete(i + 4) * gDiameter(i + 4) * gDiameter(i + 4) * gDiameter(i + 4)
                        
                      Next i
                      
                      For i = 0 To 41
                         
                        pm10t = pm10t + gDataInDiamete(i + 4) * gDiameter(i + 4) * gDiameter(i + 4) * gDiameter(i + 4)
                      
                      Next i
                                                         
                      pm25t = pm25t * 1.7 * 3.14159 * 0.00001 / 3
                      pm10t = pm10t * 1.7 * 3.14159 * 0.00001 / 3
                      pm25 = pm25 + pm25t
                      pm10 = pm10 + pm10t
                      count_t = count_t + 1
                      gSaveFileFlag = 0
                      If (count_t = 20) Then
                       
                       pm25 = pm25 / count_t
                       pm10 = pm10 / count_t
                       pm25 = Format(pm25, "#.####")
                       pm10 = Format(pm10, "#.####")
                                          
                       If gAutoSave = 1 Then
                         '自动保存文件
                            If gSaveFileFlag >= gSaveFileCycle Or gSaveFileFlag = 0 Then
                            '周期到
                             AutoSaveFile
                             gSaveFileFlag = 1
                            ' End Select
                           End If
                        End If
                        count_t = 0
                        pm25 = 0
                        pm10 = 0
                                     
                       End If
                     
                     
                 ' //接下来是64个强度通道的生物粒子荧光强度
                    sSum = 0
                    
                    'For i = 0 To 51
                       ' For j = 0 To 63
                      '      rs_sIntensityData(i + 1, j + 1) = 0
                       '     rs_sIntensityData(i + 1, j + 1) = vbReceive(2 + 2 * i * 64 + 2 * j) * 256 + vbReceive(2 + 2 * i * 64 + 2 * j + 1)
                      '  Next j
                   ' Next i
                    
                  For j = 0 To 65
                       gChannelData(j) = 0
                       'For i = 0 To 52
                          '  rs_pIntensity(j) = 0
                            '   rs_pIntensity(j) + rs_sIntensityData(i, j)
                       'Next i
                       sSum = 0                   'sSum + rs_pIntensity(j)
                    Next j
                   
                    TransitSign = True
                   Else
                    runstop
                    Call Stopd_Click
                     wait (1000)
                    Call Start_Click
                End If
                    '这里可以不作拷贝,在上面直接用gDataInDiamete,这样可以节省oncomm的运行时间
                'CopyData gDataInDiamete, rs_sChannelData
                'CopyData gChannelData, rs_pIntensity
                    '可能这个地方比较费时
                ShowDiameterData False
                'ShowChannelData False
                ShowDpsAndFrq Picture5, dSum \ 3, sSum \ 3
                    '以上是绘图的部分,可能会比较费时
                Text5.Text = str(dSum \ 3)
                Text6.Text = Format(pm25t, "#.####")
                Text1.Text = Format(pm10t, "#.####")
                MSComm1.InBufferCount = 0 '...清空输入寄存器
                timer4public = 1
            End If
        End If
    End Sub