PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Digitalmultimeter c# problem



didi34
02.02.2012, 16:58
Ich habe mir mit einem µController ein Voltmeter gebaut, welches daten über RS232 an meinen PC sendet. Sende ich meine gemessenen Werte alle 10 ms funktioniert es einwandfrei, jedoch wenn ich mit 1 ms sende kommen nicht mehr alle 5 Byte an. Wie kann ich den Code verbessern? Es werden 4 ASCII-Zeichen gesendet und ein Endzeichen 'e'.


public double messen()
{
string mess = "";
//einlesen bis Endzeichen kommt
mess = serialPort1.ReadTo("e");
//buffer entleeren
serialPort1.DiscardInBuffer();
// Bitwert auf Realen Messwert umwandeln
Messwert = Convert.ToDouble(mess) / 1023 * 5.07;
return Messwert;
}

masasibe
02.02.2012, 17:52
Mit welcher Baudrate sendest du denn?
Bei einer Baud von 1200Byte/s bräuchte jedes Byte ja schon 0,833ms und dann gehen sich 5Byte/ms natürlich nicht mehr aus.

mfg masasibe

didi34
02.02.2012, 18:26
Baud ist ok. Ich sende mit 9600 baud. Ich sende den string "1023" und bei mir kommt manchmal "123" manchmal "102" manchmal "" usw. an.

lokirobotics
03.02.2012, 14:25
Dein C# Programm wird die Daten nicht schnell genug aus dem (Virtual)COM Port holen. Vom Read bis zum DiscardInBuffer werden schon wieder Zeichen angekommen sein.
Ich halte 1kHz Update-Rate über den Port für sehr bedenklich und auch "unschön". Ein Update mit 10Hz würde doch mehr als reichen, oder?
Also immer 100 Werte im Controller sammeln und dann in einem rüber damit. Das lässt die Schnittstelle länger frei, reduziert den Overhead und du kommst mit deinem nicht so schnellen PC hinterher ;D

Besserwessi
03.02.2012, 16:16
Auch bei 9600 Baud braucht ein Byte schon etwas über 1 ms !. Bei 1200 baud sind das 0,83 ms für ein Symbol, und man braucht in der Regel 10 Symbole für 1 Bytes, also gut 8 ms.
Wenn man wirklich 1 ms braucht hilft nur eine höhere Baudrate ( >=20000) und dann ggf. noch eine binäre Übertragung. Die 10 bit kann man auch in 2 Bytes übertragen, einfach 1 Bit für die Identifikation der Datenhälften reservieren. Zur Not auch mit 19200 Baud und dann nur 6 oder 7 Bit Datenpakete.

masasibe
03.02.2012, 16:27
Oh du hast Recht! Die Baud gibt die Symbole und nicht die Byte/s an.
Jetzt verstehe ich auch, warum man bei einer Baud von 1200 quasi zuschauen kann, wie die Daten ankommen.
Das sind dann ja nur 120 Byte/s, wenn ein Byte 10 Symbole braucht.

Tja wieder etwas dazugelernt! ;-)

didi34
03.02.2012, 18:57
Das Problem dürfte nicht an der Baudrate liegen. Wenn ich mir das Signal mit dem PUTTY ansehe, kommen die Werte perfekt.

masasibe
03.02.2012, 19:14
Meinst du nicht, dass es wirklich daran liegen könnte, dass während dem Zurücksetzen des Buffer schon wieder neue
Daten hineingeschrieben wurden, so wie lokirobotics schrieb.
Hast du es schon einmal auf die Weise probiert, die lokirobotics dir geraten hat?
Also mit dem Zwischenspeichern einiger Werte auf dem µC und dem Übertragen von mehreren Werten auf einmal an den
PC.

o.g.1985
04.02.2012, 02:18
Ich hatte auch mal ein Buffer Problem das der Buffer schon wieder beschrieben wird werde er noch gelesen wird Mach zwei Buffer ! Die wie ein Flipflop funzen.
In der Zeit wo der eine Buffer gelesen wird, wird der ander Buffer beschrieben !

Eft hilft das.

MFG Oliver G

didi34
04.02.2012, 06:53
Ich hatte auch mal ein Buffer Problem das der Buffer schon wieder beschrieben wird werde er noch gelesen wird Mach zwei Buffer ! Die wie ein Flipflop funzen.
In der Zeit wo der eine Buffer gelesen wird, wird der ander Buffer beschrieben !

Eft hilft das.

MFG Oliver G
Wie meinst du das? Kann ich einen Zweiten Eingangsbuffer erstellen? Kannst du vielleicht ein Codebeispiel posten?
Vielen dank für deine Antwort.

o.g.1985
04.02.2012, 13:49
OK mach ich aber ich würde aber auch gerne mas sehn wie du die Daten von Comport holst. ( Event-Handler usw.. )

Buffer erstellen:

byte[] M_byte_Buffer_01 = new byte[5];
byte[] M_byte_Buffer_02 = new byte[5];

Wenn du die Daten hast werden sie abwechselnd in M_byte_Buffer_01 / M_byte_Buffer_02 geschickt ! Und zu gleich holst du die Daten von M_byte_Buffer_01 / M_byte_Buffer_02. Aber nicht von den die gerade beschrieben werden ;)

PS: Wenn man es jetzt genau nimmt ist es 3 fach gepuffert! Ich hab vergessen das beim:
( serialPort1 System.IO.Ports.SerialPort ) Puffer dabei sind?
Wie gross ist "ReadBufferSize" bei dir ?

MFG Oliver G

didi34
05.02.2012, 12:12
Danke für die Antwort. Ich überlege aber auf USB umzusteigen, dann Hatte ich die Übertragungsprobleme nicht mehr. Kennt sich da jemand aus mit der USB-Kommunikation in C#. Und auch wie ich das mit einem USB-Fähigem Atmell µC mache?

didi34
05.02.2012, 12:48
Aber Vielleicht bleibe ich doch bei RS232. Hier ist mein Code. Hoffentlich weiß jemand, wie ich es verbessern könnte. Ich verwende einen 6 Byte buffer und das Data_Recive Event wird nach 5 empfangenen Bytes ausgelöst.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using NationalInstruments;
using NationalInstruments.UI;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public static double Messwert;
public static int werte = 0;
public static double[] dataValues = new double[200];
public Form1()
{
InitializeComponent();
serialPort1.Open();
}



private delegate void SetTextDeleg(double text);
public void serialPort1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
double messval = messen();
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { messval });
waveformGraph1.PlotY(dataValues, 0, 10, 0, 5);

}


private void si_DataReceived(double data)
{
label1.Text = data.ToString();
meter1.Value = data;
}




public double messen()
{
string mess = "";
mess = serialPort1.ReadTo("a");
serialPort1.DiscardInBuffer();
try
{
Messwert = Convert.ToDouble(mess) / 1023 * 5.07*2.794;
dataValues[i] = Messwert;
i++;
}
catch
{
serialPort1.DiscardInBuffer();
}
return Messwert;
}


}
}