Also ich habe einen Prüfstand entwickelt, der auch per CAN-Bus am PC hängt.
Ich verwende dazu den IXXAT Adapter.
Vielleicht kann ich dir ja weiterhelfen, wenn ich mal dein Problem richtig kenne
Ich muß relativ viel mit SerialPort machen, und mir ist nicht aufgefallen dass ich in dem Event schon Pakete verloren habe.
So, jetzt hab ich endlich mal Zeit!
Die Clients schicken schon auch was. Aber das fällt absolut nicht ins Gewicht.
Hab nach einigem testen nun auch eine akzeptable Lösung für mein Problem hinbekommen.
Was ich aber gar nicht verstehe: Bei 10 angemeldeten Clients, serieller Port feuert mit 9600 Baud, habe ich auf einer Win7 x64 mit i5 Cpu Kiste eine Last von ca. 5-10%, auf einem alten DualCore XP x32 zwischen 1 und 3% bei etwa der gleichen Performance.
Kann mir das jemand erklären?
Btw.: Danke an ujr, herbi und weismat. Die Kombination aus den Posts hat mich auf den richtigen Weg gebracht
Ich habe mich an die MSDN gehalten:
Einen Multithreading-TCP-Netzwerkserver erstellen
Aufgabe
Sie möchten einen TCP-Server erstellen, der mehrere TCP-Clients gleichzeitig bearbeiten kann.Lösung
Benutzen Sie die Methode AcceptTcpClient der Klasse TcpListener. Starten Sie immer dann, wenn ein Client eine Verbindung herstellen möchte, einen neuen Thread, um die Anforderung zu bearbeiten. Rufen Sie in diesem Fall außerdem TcpListener.AcceptTcpClient erneut auf.
Ich habe einen Dienst geschrieben, der alles was vom seriellen Port kommt auf einen Tcp-Socket leitet.
Da ich nicht ausschliessen kann dass sich mehrere Clients anmelden, mache ich für jeden Client einen extra Sendethread auf.
Bei einem, oder zwei Clients ist alles noch akzeptabel. Da ich aber den Tcp Thread per ManualResetEvent mit dem seriellen Thread synce skaliert die Performance auf Tcp Seite nehativ pro Client. Ist ja auch klar, da der Tcpthread ja immer länger warten muss.
Was wäre hier die bessere Methode um diesen Effekt nicht zu haben?
Ich hatte es auch schon so dass die CPU-Last pro Client skaliert. Ist aber noch weniger akzeptabel, wenn diese dann bei 4 Clients bei ca. 60% auf einer i5 liegen...
Ich musste erst googeln, was das überhaupt sein soll. Du meinst Cisco? Kann ich mir jetzt nicht vorstellen.
Nein, ich meine SICS von METTLER TOLEDO.
Über dieses Protokoll kann man die Waagen und Terminals ansteuern, und natürlich auch Daten erhalten.
Hallo zusammen,
weiß zufällig jemand ob es schon fertige Klassen für SICS gibt?
Warum ersetzt du nicht einfach den Windows-Explorer durch deine Anwendung?
Dann wird beim Start von Windows einfach deine Anwendung geladen, ohne Desktopschnickschnack ...
Ich weiß, der Thread ist gute zwei Jahre alt, aber hat sich jemand schon mal wer den/das Gadgeteer von MS angeschaut?
Die Info's dazu sind ja leider relativ dürftig, wenn man mal von ein paar Demovideos absieht...
Ist das ganze nun doch eingeschlafen, oder wird einfach nur fleißig daran gearbeitet?
Nachdem der letzte Beitrag aber schon über ein Jahr alt ist befürchte ich eher ersteres 🙁
Wirklich doofe Aufgaben habe ich so gut wie nie.
Vielleicht liegt es daran dass ich in keiner Softwareschmiede arbeite, sondern in einem Industriebetrieb?! Hier gibts meist eher zuviel Abwechslung.
Wenn was nervt, dann ist es meist, wenn ich irgendeine App schreiben muß, die von unseren "tollen" SQL-Datenfriedhöfen lebt. Aber dann eben Augen zu, und durch!
Ansonsten liebe ich meinen Job. Man lernt ständig neues dazu, wie z.B. embedded Systems, versch. Bussysteme, optimierung von Bertiebsabläufen, Automatisierung usw.
Das ganze wird ein Prüfstand, bei dem ich ein Wegsignal eines LVDT ins Verhältniss zu anderen Messergebnissen setze.
Ich muß also sicherstellen das erstens alle Ergrbnisse zueinander passen (vom timing her) und das es natürlich auch grad die aktuellen sind.
Senden tu ich schon auch. Aber relativ wenig. Ich kann zb die PDO-Rate einstellen, PDO ganz an- und abschalten, die Statemachine abfragen etc.
Dies alles findet aber nicht zyklisch statt, sondern nur auf Wunsch des Anwenders.
Ich kenne den Wrapper nicht, aber ich denke du wirst deinen Eventhandler nach dem erneuten öffnen nochmals initialisieren müssen
private Serial ComPort;
ComPort = new Serial("COM2:", 9600);
ComPort.Open();
ComPort.OnDataReceived += new Serial.OnDataReceivedEventHandler(OnData);
// Ca. 7 Sekunden Verzögerung beim Umstellen der Baudrate aufgrund Austausch der Anfangstelegramme
ComPort.OnDataReceived -= new Serial.OnDataReceivedEventHandler(OnData);
ComPort.Close();
ComPort.ComPort = "COM2";
ComPort.Baudrate = 38400;
ComPort.Open();
ComPort.OnDataReceived += new Serial.OnDataReceivedEventHandler(OnData);
Frage a: hast Du schonmal probiert ohne AsParallel zu arbeiten. Ich weis zwar nicht was für Werte Du in deiner List verarbeitest.. aber lass mal folgenden Code durchlaufen, und Du wirst sehen was ich meine.. Ich schätze AsParallel hat hier einen zu hohen overhead
Ich werde es mir nochmals genauer anschauen. Bisher konnte ich nur feststellen dass mit der Parallel Methode die CPU-Kerne etwas gleichmäßiger ausgelastet sind.
Frage b: muss das unbedingt jede millisekunde passieren?
Für eine Anzeige.. z.B. GUI reicht es höchstwarscheinlich das alle 300 - 500ms zu machen.
Ich spüre, selbst in der GUI, schon eine Erhöhung auf 2ms relativ deutlich. Dort wäre dies natürlich durchaus vertretbar, aber da ich ja nicht nur visualisieren muß, sondern auch tatsächlich mit den Werten arbeiten sollte ... 😉
Hallo Gemeinde,
ich sitze z.Zt. an einem Projekt bei dem ich an einem IXXAT USB-To CAN-Compact Adapter 6 Slaves am CAN-Bus hängen hab.
Jeder der Slaves sendet per PDO. Ein Slave mit 1ms und 10ms Interval, die restlichen 5 mit jeweils nur 10ms.
Im Moment arbeite ich mit einem Producer-Thread, der alle(?) Daten vom Bus aufnimmt, und 2 Consumer-Threads zum Aufbereiten der Daten. Dann noch jeweils einem Thread zum aktualisieren der entsprechenden Controls der GUI.
Den Sync, in den Consumern und GUI, erledige ich zum Grossteil mit der Monitorklasse (TryEnter, Wait & Pulse). Im Producer mit AutoResetEvent...
Bei einem Slave läuft alles noch relativ rund, wenn aber alle sechs "feuern" geht meine Performance aber doch deutlich in die Knie! Buslast ist aber noch gut im "grünen Bereich". Ok, sind dann ja auch nicht gerade wenig Daten.
Hat hierzu evtl. jemand Tipps, Erfahrung oder sogar ein Workaround?
Wie nah bin ich denn überhaupt an Echtzeit?
Wieviele Daten gehen verloren?
Ist .Net in diesem Bereich überhaupt zu empfehlen?
Natürlich gibts auch noch ein paar Besonderheiten. Die Daten des 1ms Intervals lasse ich mir z.B. in eine List schreiben, in der ich aus 500 Werten, per AsParallel().Average() den Durchschnitt fließend berechnen lasse. Sprich pro neuem Wert fällt hinten einer raus. Ich hatte diese Berechnung zuerst auf dem Slave per Eventhandler implementiert, aber das brachte den 10kHz-Cycle der Elektronik aus dem Tritt X(
Aber bevor ich hier jetzt unnötig in die Tiefe gehe wäre es ja erstmal interessant ob's hier Leute gibt die mit solchen Dingen überhaupt schon mal in Berührung kamen 😉
Ich freue mich auf reichlich Antworten, Tipps, Tricks und Workarounds von euch
Btw.: Das ganze läuft auf einer Intel i5 CPU unter W7 prof. x64
Du könntest dir aber auch einen USB-Seriell-Adapter von z.B. Keyspan zulegen.
Diese bringen schon einen einfachen Sniffer mit. So kannst du immer sehen was auf dem Port so abgeht.
Ich könnte mir für deine Anforderung auch gut eine Art Y-Kabel vorstellen.
Auf der einen Seite deine Maschine, die 2 anderen Ende auf jeweils einen Comport auf der PC-Seite.
Bei mir gehts einfach nicht. Zumindest mit IMAP.
Könnte es denn vielleicht noch mit dem Server zusammenhängen?
Bestehende eMails, die schon mal geöffnet wurden, werden korrekt angezeigt, ungelesene sind auch wieder ohne Body.
Ich kanns von zu hause leider nicht nachstellen aber morgen von Arbeit aus.
Wie ist dein Workflow, woher bekommst du die EntryIDCollection ?
Ist das einem Event, wenn ja von welchem?
Das Event kommt von
_Explorers.Application.NewMailEx += new ApplicationEvents_11_NewMailExEventHandler(Application_NewMailEx);
habs aber auch schon mit
_Inspectors.Application.NewMailEx += new ApplicationEvents_11_NewMailExEventHandler(Application_NewMailEx);
versucht, mit dem gleichen Ergebnis bei IMAP und POP3
Dachte erst dass die Weiterleitung der Mail an Lotus Notes das große Problem wird, aber das war völlig easy. Und jetzt spielt ausgerechnet Outlook nicht mit X(
geben dir
mailItem.BodyFormat
mailItem.HTMLBody
mailItem.RTFBodyvielleicht was raus?
Also der HTMLBody gibt mir einfach den leeren Standardheader zurück. <Body> ist einfach leer.
RTFBody, nach der Umwandlung von ByteArray nach String enthält zwar ein paar Infos, aber der eigentliche Text ist nicht enthalten.
BodyFormat ist "Plain".
Ich habe die Mail auch schon in allen drei Formaten an die überwachte Adresse geschickt, mit immer dem gleichen Ergebnis.
Ich denke es bleibt echt nur noch der Unterschied zwischen POP3 und IMAP
Na dem Fall ist das Property dann doch unverdächtig, es sah nur so verdächtig danach aus. Was mir nicht in den Kopf will ist das du im Einzelschrittdurchlauf den richtigen Wert bekommst. Allerdings scheint der Effekt nicht untypisch
>
auch wenn er mir noch nie untergekommen ist.
Versuche mal testweise eine Zeitfeder einzubauen um diese These erstmal zu bestätigen das Outlook irgendwie einfach nicht hinterher kommt.
Auch das will nicht klappen!
Selbst wenn ich in einer while-Schleife den Body auf null prüfe kommt er nie aus der Schleife raus.
Im Einzelschritt klappt das übrigends nicht jedesmal! Aber nach dem Test mit der Schleife gehe ich mal nicht von einem Timingproblem aus.
Ich vermute eher das dein Property OutlookBody das Problem ist.
Du meinst das
public string OutlookBody { get; set; }
Ärger machen könnte?
Also ich habe jetzt einfach Testhalber einen POP3-Account eingerichtet, und alles funktioniert wie erwartet.
Es muss also irgendwie daran liegen wie IMAP-Mails von Outlook behandelt werden.
Hat ja jemand evtl. eine Idee?
Werden bei IMAP evtl. nur die Kopfzeilen geladen, und der Rest erst wenn man die Mail auch tatsächlich öffnet? Wenn ja, wie komm ich dann an den Body?
Hi zusammen.
Ich versuche neu ankommende eMails aus Outlook 2010 auszulesen.
Also "Subject", "Body" usw ...
Alles klappt soweit auch, nur dass eben Body immer den Wert null aufweist.
Es kommt aber teilweise auch vor, wenn ich den Code im Einzelschritt durchlaufe (F11) dass dann der Body die richtigen Zeichen enthält.
Woran kann das denn bitte liegen?
void Application_NewMailEx(string EntryIDCollection)
{
var newMail = (MailItem) _Explorers.Application.Session.GetItemFromID(EntryIDCollection, Missing.Value);
OutlookSubject = newMail.Subject;
OutlookBody = newMail.Body;
OutlookTo = newMail.To;
MessageBox.Show(OutlookBody, OutlookSubject);
}
Btw: Es handelt sich um einen IMAP-Account, falls dies einen Unterschied macht
Es eignen sich praktisch alle Zeichen die man per Tastatur nicht so leicht erzeugen kann.
Dumme Frage: Aber warum ist es wichtig zu unterscheiden, woher die Eingabe kommt? Geht es dir nur um die Verfizierung der Prüfziffer hinterher, oder gibt es noch einen anderen Grund?
Fragen sind nie dumm 😉
Ich möchte (muss) verhindern dass in einer der Textboxen manuell etwas eingegeben werden kann. Es darf dort eben nur eine Eingabe per Barcodescanner erfolgen.
Einfach um Fehleingaben (Manipulationen?) zu vermeiden.
Ich werde diesen Ansatz wohl doch auch noch testen.
Bisher hab ich mir zwei Eventhandler gebaut, einer der beim Startzeichen, und einer der beim Endezeichen triggert. So kann ich recht komfortabel reagieren.
Was mir allerdings bei dem Ansatz mit dem timing sehr gut gefällt, er ist nicht so sehr von der Scannerhardware abhängig.
Was passiert bei einer Copy - Paste Aktion?
So einfach ist das auch wieder nicht.
Du müßtest dann auch auf eine Mindesteingabelänge prüfen, denn du darfst auch den frustrierten Lagerarbeiter nicht vergessen, der einfach mal auf paar Tasten haut 😉
Nach ein wenig stöbern und ausprobieren kamen für mich nur zwei Möglichkeiten in Betracht:
Man konfiguriert den Scanner so dass er eine RS232 emuliert. Dann ist alles natürlich gar kein Problem mehr. Der Nachteil dabei ist, man braucht natürlich einen Herstellertreiber für den virtuellen Port.
Man konfiguriert den Scanner als HID, und läßt ihn dann Sonderzeichen vor und nach dem Scan ausgeben. Am besten wählt man dafür natürlich Sonderzeichen, die nicht so einfach über die Tasttatur getippt werden können. Bei meinem Modell kann man sogar mehrere und verschiedene Zeichen für Anfang und Ende definieren.
Der Vorteil dieser Methode ist ganz klar: Das Gerät bleibt Plug ´n Play fähig. Der Nachteil ist eben dass man etwas mehr Code tippen muß. Den Aufwand sollte man aber gerne in Kauf nehmen.
LibUSB ist natürlich auch noch eine Möglichkeit. Dann wird das Programm aber relativ unflexibel, da, wenn der Scanner mal getauscht werden muss, man entweder den Quellcode anfassen muß, oder aber zumindest die Konfiguration ändern muß.
Das wäre eine feine Sache.
Ich werd mich dann erst mal bei Datalogic umschauen ob dies mit meinem Modell möglich ist.
Ich bin aber auch für weitere Vorchläge bzw. Ansätze offen.
Hallo zusammen,
hat von euch vielleicht jemand eine Idee wie man die Eingaben eines USB-Barcodescanners von Eingaben einer Tastatur unterscheiden könnte?
Erstens hat er eine Betriebs-LED und zweitens ist dies ja nur ein Codeausschnitt zum testen. Im richtigen Programm ist auch ein Eventhandler für den Empfang. Und es wird eben so lange empfangen bis ich das XML in das DataSet lade ...
Aber du hattest vollkommen Recht:
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;
namespace DataSet_SeriellerPort
{
public partial class Form1 : Form
{
private SerialPort _sp;
public SerialPort Sp
{
get { return _sp; }
set { _sp = value; }
}
public Form1()
{
InitializeComponent();
Sp = new SerialPort("COM5");
Sp.Open();
DataSet dt = new DataSet();
dt.InferXmlSchema(@"C:\Abtragswerte.xml", new string[] { "" });
dt.ReadXml(@"C:\Abtragswerte.xml");
dataGridView1.DataSource = dt;
dataGridView1.DataMember = "Abtragswerte";
}
}
}
funktioniert. Hätte ich eigentlich nicht gedacht ...
Dankeschön! 😮
Hallo zusammen.
Kann mir jemand erklären warum bei folgendem Code der serielle Port geöffnet, aber nach der aktualisierung des DataGridView wieder geschlossen wird?
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;
namespace DataSet_SeriellerPort
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SerialPort sp = new SerialPort("COM5");
sp.Open();
DataSet dt = new DataSet();
dt.InferXmlSchema(@"C:\Abtragswerte.xml", new string[] { "" });
dt.ReadXml(@"C:\Abtragswerte.xml");
dataGridView1.DataSource = dt;
dataGridView1.DataMember = "Abtragswerte";
}
}
}
Das mit dem Trigger sieht gut aus!
Das der SQL bei UPDATE eigentlich ein DELTE und dann ein INSERT ausführt hab ich zugriff auf den alten und neuen Wert.
Das wird was 👍
Frage am Rande:
Du willst eine Spalte erfinden, die sich nach Übergabe eines Wertes automatisch addiert, egal woher diese Daten kommen?
Richtig!
Also jegliche anderen Programme von beliebigen Herstellern, die sich an deine Vorgaben nicht halten und einfach irgendwas mit deinen Daten tun, sollen als Ergebnis einen richtigen Wert erhalten?
Nein, sie sollen nichts zurück bekommen. Nur in der besagten Spalte soll die Summe stehen.
@Abt
Das klingt gut. Ich werde das mal einfach so testen.
Prinzipiell stimmt das schon so! Nur, wie gesagt, werden auch andere Programme, die nicht von mir sind, in diese Zeile Zahlen eintragen. Und auch da muß sichergestellt sein dass der Server diese Zahl zu der bestehenden addiert, und somit wieder nur die Summe auf dem Server liegt.
An sowas hatte ich auch schon gedacht, muß aber zugeben noch nie etwas mit Triggern gemacht zu haben.
Aber wenn das der richtige Weg ist, dann werde ich mich da gerne reinlesen
Langsam kommen wir der Sache näher.
Nur möchte ich ja nicht neue Zeilen erzeugen, sondern in einer einzigen immer die Summe aktuell haben.
Ich muss aber davon ausgehen dass nicht mein Programm alleine dort irgendwelche Zahlen reinwirft, ich muss aber sicherstellen dass sie eben alle addiert werden.
Daher eben die Idee dies Serverseitig zu machen.
Fast.
In einer Spalte, nennen wir sie "Summe", steht '5'. Nun teile ich dem SQL einen neuen Wert '4' mit. Er soll nun die '5' durch eine '9' ersetzen.
Was ist Strange daran?
Wenn ich getdate() als ComputedColumnSpecification eintrage dann schreibt er mir für jede neue Zeile das Datum an die entsprechende Stelle. Genauso wie ich z.B. die ID inkrementieren lassen kann.
Und natürlich möchte ich ihm einen neuen Wert vorgeben, aber die eigentliche Addition möchte ich eben auf der SQL-Seite haben, und nicht im Code des C# Programms.
Das würde sicher gehen. Es gibt wohl eine ganze Anzahl von Lösungen hierfür.
Ich wollte lediglich wissen ob der Server diese Berechnung nicht selbst ausführen kann. Also ähnlich wie getdate() bei dem er ja auch das Datum selbst einträgt.
verwendetes Datenbanksystem: <MS SQL 2008>
Hallo
Ich möchte in einer Datenbank zu einem schon bestehenden Dezimalwert einen neuen immer dazuaddieren.
Gibt´s dafür evtl. eine Möglichkeit dies per ComputedColumnSpecification schon auf dem SQL-Server zu erledigen, oder muss ich tatsächlich erst den bestehenden Wert auslesen, die Summe mit dem neuen Wert bilden, und das Resultat wieder zurückschreiben?
Also irgendwie finde ich da keinerlei Ansatz ...
Ich hab jetzt echt stundenlang gegoogelt, finde aber rein gar nichts wie man per CLI an diese Einstellungen kommen könnte.
Mir würde auch irgendein Batch reichen ...
Ich gebs auf! Scheint keine Lösung dafür zu geben ...
Hat das Ding keine GPIB Schnittstelle??
Hallo zusammen,
ich weiß, das Thema wurde schon ein paar mal angeschnitten, und auch Google gibt ein wenig Auskunft darüber.
Leider bin ich dabei aber immer wieder nur zum Thema IP-Adresse, DHCP, und DNS-Server fündig geworden.
Ich müßte aber quasi die Haken setzen können vor "Client für Microsoft Netzwerke", "Datei-und Druckerfreigabe für Microsoft Netzwerke" etc.
Weiß jemand wie ich da ran komme?
Okee... Geht aber nicht wenn ich z.B. ein DataGridView im Designer an eine Table des SQL gebunden habe, oder?
verwendetes Datenbanksystem: SQL 2005 bzw. SQL 2008
Hallo zusammen,
ich hab mal eine kurze Frage.
Ist es überhaupt möglich Änderungen im Datensatz, die von einem anderen Programm in einer Datenbank gemacht werden, quasi live in einem C# Programm darzustellen?
Also ohne ständiges pollen natürlich.
Danke schonmal