Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Powershell und Kommunikation (lesen und schreiben) mit RS-232, COM1, serielle Schnittstelle

Frage Entwicklung Batch & Shell

Mitglied: DonniDuck

DonniDuck (Level 1) - Jetzt verbinden

11.03.2013, aktualisiert 16:46 Uhr, 7851 Aufrufe, 3 Kommentare

Hallo,
über die Powershell soll ein externes Gerät mit serieller Schnittstelle(RS232/COM1) angesprochen und gesteuert werden. Das Senden der Daten an das Gerät stellt kein Problem dar.

Allerdings habe ich große Probleme die seriellen Daten korrekt zu empfangen, da Daten verloren gehen bzw. die Übertragung nicht stabil läuft!

Mein erster Ansatz für die Lösung dieser Aufgabe war folgender Beitrag auf der Microsoft-Webseite mit folgenden Quellcode:

01.
#Daten schreiben  
02.
 
03.
$port= new-Object System.IO.Ports.SerialPort COM1,9600,None,8,one 
04.
$port.open() 
05.
$port.WriteLine("Hello world") 
06.
$port.Close() 
07.
 
08.
#Daten lesen 
09.
 
10.
$port= new-Object System.IO.Ports.SerialPort COM1,9600,None,8,one 
11.
$port.Open() 
12.
$port.ReadLine()
Die Steuerung des Gerätes erfolgt nach folgenden Schema:
  1. Befehl senden
  2. Daten lesen/empfangen
  3. Befehl senden
  4. Daten lesen/empfangen
  5. usw.

Erster Beispielquellcode
01.
#INIT => Allgemein 
02.
[string]$buffer = " "; 
03.
 
04.
# Befehlsyntax für RS-232-Gerät 
05.
[string]$rs232_event_check = "/event/log/entries ?`r"; 
06.
[string]$rs232_event_transfer = "/event/log/read ?`r"; 
07.
 
08.
# INIT => Eigenschaften der seriellen schnittstelle 
09.
$port = New-Object System.IO.Ports.SerialPort; 
10.
 
11.
[string]$port.PortName = "COM1"; 
12.
[int]$port.BaudRate = 19200; 
13.
[int]$port.DataBits = 8; 
14.
[string]$port.Parity = "None"; 
15.
[string]$port.StopBits = "One"; 
16.
[string]$port.Handshake = "XOnXOff"; 
17.
 
18.
# START => Kommunikation 
19.
 
20.
# RS-232-Kommunikation => START 
21.
$port.Open(); 
22.
# RS-232-Kommunikation => Gerät ansprechen 
23.
$port.WriteLine($rs232_event_check); 
24.
# RS-232-Kommunikation => Gerätdaten abfragen 
25.
$buffer = $port.ReadLine(); 
26.
# Testausgabe auf Konsole 
27.
echo $buffer; 
28.
$port.WriteLine($rs232_event_check); 
29.
$buffer = $port.ReadLine(); 
30.
echo $buffer; 
31.
 
32.
# RS-232-Kommunikation => ENDE 
33.
$port.Close()
Das angesprochene Gerät sendet nach dem Empfangen des Befehls sofort eine Antwort, je nach Abfragegeschwindigkeit werden nicht alle Daten übertragen bzw. gehen verloren!

Deshalb möchte ich das Empfangsregister (Puffer/Buffer) über eine Ereignisabfrage (Interrupt/Flag) abfragen. Nur wenn neue Daten anliegen erfolgt eine Abfrage der Daten und eine Auswertung auf das Abschlusszeichen. Allerdings ist hierzu die Dokumentation von Microsoft und im Internet bezogen auf die Powershell dürftig.

Für die Abfrage soll die Methode DataReiceved() genutzt werden, allerdings komme ich hier nicht weiter, da der Code von Microsoft nicht für die Powershell ist?! Wie kann ich diese Methode und das Abfragen der Events korrekt in die Powershell einbinden?

In folgenden Artikel wird auf diese Thematik eingegangen:
1. SerialPort and DataReceived Event
2. Top 5 SerialPort Tips

Mitglied: Friemler
11.03.2013, aktualisiert um 19:32 Uhr
Hallo DonniDuck,

schau mal hier und hier nach. Dort sind zwar nur Beispiele für Timer-Events, das sollte sich allerdings auf Deinen Fall übertragen lassen.

Evtl. so (ungetestet):
01.
$rs232_event_check = "/event/log/entries ?`r"; 
02.
$rs232_event_transfer = "/event/log/read ?`r"; 
03.
 
04.
$port = new-Object System.IO.Ports.SerialPort 
05.
 
06.
$port.PortName = "COM1" 
07.
$port.BaudRate = 19200 
08.
$port.DataBits = 8 
09.
$port.Parity = "None" 
10.
$port.StopBits = "One" 
11.
$port.Handshake = "XOnXOff" 
12.
 
13.
$null = Register-ObjectEvent $port DataReceived -SourceIdentifier "SerialPort.DataReceived" -Action {OnDataReceived} 
14.
 
15.
$port.Open() 
16.
$port.WriteLine($rs232_event_check) 
17.
 
18.
Start-Sleep -Seconds 2 
19.
 
20.
$port.Close() 
21.
 
22.
Unregister-Event -SourceIdentifier "SerialPort.DataReceived" 
23.
 
24.
 
25.
 
26.
function OnDataReceived { 
27.
  $response = $port.ReadLine() 
28.
  echo $response 
29.
}
Gruß
Friemler
Bitte warten ..
Mitglied: DonniDuck
12.03.2013 um 11:32 Uhr
Hallo Friemler,

vielen Dank für den Denkanstoß, was mich auf jeden Fall schon ein gutes Stück weiter bringt, hier die aktuelle Version - leider ohne korrekte Funktion:

01.
# INIT => Allgemein 
02.
 
03.
[string]$buffer = " "; 
04.
[string]$rs232_event_check = "/event/log/entries ?`r"; 
05.
[string]$rs232_event_transfer = "/event/log/read ?`r"; 
06.
 
07.
# INIT => Eigenschaften der seriellen schnittstelle 
08.
 
09.
$port = New-Object System.IO.Ports.SerialPort; 
10.
 
11.
[string]$port.PortName = "COM1"; 
12.
[int]$port.BaudRate = 19200; 
13.
[int]$port.DataBits = 8; 
14.
[string]$port.Parity = "None"; 
15.
[string]$port.StopBits = "One"; 
16.
[string]$port.Handshake = "XOnXOff"; 
17.
 
18.
# INIT => Funktionen 
19.
 
20.
function GET_RS232-DATA { 
21.
 $buffer = $port.ReadExisting(); 
22.
 write_host "Interrupt"; 
23.
 write_host $buffer; 
24.
25.
 
26.
# INIT => Interrupts 
27.
 
28.
Register-ObjectEvent -InputObject $port -EventName DataReceived -Action {GET_RS232-DATA} -SourceIdentifier Status_RS232;  
29.
 
30.
########################################################## 
31.
# START 
32.
########################################################## 
33.
 
34.
$port.Open(); 
35.
$port.WriteLine($rs232_event_check); 
36.
Start-Sleep -Seconds 10; 
37.
$port.Close(); 
38.
Unregister-Event -SourceIdentifier Status_RS232;
Der Interrupt bzw. das Ereignis wird vermutlich korrekt eingerichtet, allerdings springt er nicht in die Funktion und gibt die Testausgabe auf der Konsole aus!

Beim Starten des Programmes wird folgende Ausgabe auf die Konsole geschrieben:

Id              Name            State      HasMoreData     Location             Command                   
--              ----            -----      -----------     --------             -------                   
2               Status_RS232    NotStarted False                                GET_RS232-DATA
Ein Anhaltspunkt dafür, dass die Ereignisabfrage korrekt eingebunden ist, allerdings wird in der Spalte "State" das Problem liegen! Es fehlt mir vermutlich noch ein Parameter bzw. Schalter zum automatischen initialisieren der Ereignisabfrage?

Microsoft schreibt dazu:
Use the DataReceived event on the port object with the Register-ObjectEvent cmdlet.

Was ja im Quellcode in Zeile 28 schon vorgenommen wurde!

Der Befehl "$port | Get-Member -MemberType Event" bringt folgende Anzeige auf die Konsole:

TypeName: System.IO.Ports.SerialPort 
 
Name		MemberType	Definition                                                                                                                 
----		----------	----------                                                                                                                 
DataReceived	Event		System.IO.Ports.SerialDataReceivedEventHandler DataReceived(System.Object, System.IO.Ports.SerialDataReceivedEventArgs) 
Disposed	Event		System.EventHandler Disposed(System.Object, System.EventArgs)                                                              
ErrorReceived	Event		System.IO.Ports.SerialErrorReceivedEventHandler ErrorReceived(System.Object, System.IO.Ports.SerialErrorReceivedEventArgs) 
PinChanged	Event		System.IO.Ports.SerialPinChangedEventHandler PinChanged(System.Object, System.IO.Ports.SerialPinChangedEventArgs)
Bitte warten ..
Mitglied: Bitschubser
24.01.2014 um 18:53 Uhr
Hi DonniDuck,

ein etwas später Kommentar, aber vielleicht hilft er noch, ich hatte mir hier auch ewig den Kopf zerbrochen. Der Event wird schon getriggert, das sieht man, wenn man in der Action einfach etwas auf den Host schreibt. Nur habe ich nie Daten vom seriellen Port gesehen, bis ich nach einigem Probieren auf den MessageData-Parameter gekommen bin:

$event = Register-ObjectEvent -InputObject $port -EventName DataReceived -MessageData $port -SourceIdentifier "SerialPort.DataReceived" -Action { $event.messagedata.readexisting() | Out-Host }

Und vor dem Schließen des Ports sollte dann noch ein Start-Sleep stattfinden, sonst ist der Kanal zu bevor das Gerät fertig geantwortet hat.

Viele Grüße vom Bitschubser
Bitte warten ..
Neuester Wissensbeitrag
Internet

Unbemerkt - Telekom Netzumschaltung! - BNG - Broadband Network Gateway

(3)

Erfahrungsbericht von ashnod zum Thema Internet ...

Ähnliche Inhalte
Peripheriegeräte
gelöst RS-232 Automation (12)

Frage von Olio1965 zum Thema Peripheriegeräte ...

Batch & Shell
gelöst PowerShell - Teile eines Pfads in eine Variabel schreiben (1)

Frage von ImmerKind zum Thema Batch & Shell ...

Batch & Shell
Powershell - In Textdatei suchen und ersetzen (3)

Frage von Raaja89 zum Thema Batch & Shell ...

Batch & Shell
gelöst PowerShell Domain Join (2)

Frage von Patrick-IT zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Server
Outlook Verbindungsversuch mit Exchange (15)

Frage von xbast1x zum Thema Windows Server ...

Grafikkarten & Monitore
Tonprobleme bei Fernseher mit angeschlossenem Laptop über HDMI (11)

Frage von Y3shix zum Thema Grafikkarten & Monitore ...

Microsoft Office
Keine Updates für Office 2016 (11)

Frage von Motte990 zum Thema Microsoft Office ...