PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Relaiskarte ansteuern, übersetzen nach vb.net


tsaG
2008-05-30, 16:12:52
Hi,

Ich möchte ein Programm schreiben womit ich meine Serielle Relaiskarte ansteuern kann.
Mit sowas betrete ich im Moment noch absolutes Neuland. Ich habe also keine Ahnung wie man Ports ansteuert etc.

Ich habe dazu das Programm "conrad relais" gefunden. Dies ist genau die Karte die ich besitze, das Programm funktioniert auch ganz gut.

Dazu wird auch der passende Source Code angeboten. Jedoch ist dieses Programm leider in Visual basic und nicht in vb.net geschrieben, dh. es funktioniert nicht wenn man den Code einfach einfügt. Auch fehlen ein paar klassen wie zb MSCOMM etc. auch gibt es noch ein paar kleinere Fehler..

Nun wie kann ich das Programm nach vb.net portieren? welche Klasse wird anstatt Mscomm in vb.net benutzt?

Hier der Code zum Download: klick (http://www.map.boku.ac.at/fileadmin/_/H89/H893/AG-EW/Mechatroniklabor/conrad_8fach_relaisvb6_sourcecode.zip)
Hier das Programm zum Download:
klick (http://rapidshare.com/files/118831483/conradrelais.exe)

BTW: Das ist diese Conrad Karte (http://www1.conrad.de/fas6/fh.php?fh_params=fh_search%3Drelaiskarte%26fh_secondid%3Db2c967720%26fh_lister_p os%3D4%26fh_location%3D%252f%252fb2cconrad_de_b2c%252fde_DE%252f%2524s%253drelai skarte%26fh_eds%3D%25c3%259f%26fh_refview%3Dsearch&fh_host=http://www1.conrad.de&fh_session=/scripts/wgate/zcop_b2c/~flN0YXRlPTIwMzQ1Njk1MjM=?&fh_pic_url=//images.conrad.de&layout=b2c&fsm_host=&fsm_insertkz=), Sie läuft über den Seriellen Anschluss

Achja, und hier der Code

VERSION 5.00
Object = "{648A5603-2C6E-101B-82B6-000000000014}#1.1#0"; "MSCOMM32.OCX"
Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "mscomctl.ocx"
Begin VB.Form fmmain
Caption = "Conrad Relaiskarte"
ClientHeight = 6375
ClientLeft = 6675
ClientTop = 4590
ClientWidth = 5445
LinkTopic = "Form1"
ScaleHeight = 6375
ScaleWidth = 5445
Begin VB.Frame Frame3
Caption = "Relaiszustand"
Height = 1335
Left = 120
TabIndex = 9
Top = 4680
Width = 4815
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 0
Left = 3660
TabIndex = 17
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 1
Left = 3180
TabIndex = 16
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 2
Left = 2700
TabIndex = 15
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 3
Left = 2220
TabIndex = 14
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 4
Left = 1740
TabIndex = 13
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 5
Left = 1260
TabIndex = 12
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 6
Left = 780
TabIndex = 11
Top = 240
Width = 255
End
Begin VB.CheckBox chkrelais
Enabled = 0 'False
Height = 855
Index = 7
Left = 300
TabIndex = 10
Top = 240
Width = 255
End
End
Begin VB.Frame Frame2
Caption = "COM-Port"
Height = 1215
Left = 120
TabIndex = 6
Top = 1560
Width = 2295
Begin MSComctlLib.Slider sldcom
Height = 255
Left = 360
TabIndex = 7
Top = 720
Width = 1695
_ExtentX = 2990
_ExtentY = 450
_Version = 393216
LargeChange = 1
Min = 1
Max = 8
SelStart = 1
TickStyle = 1
Value = 1
End
Begin VB.Label lblcomport
Caption = "1"
Height = 255
Left = 960
TabIndex = 8
Top = 360
Width = 255
End
End
Begin VB.Frame Frame1
Caption = "Auswahl Relaiskarte"
Height = 1095
Left = 120
TabIndex = 3
Top = 3000
Width = 4215
Begin MSComctlLib.Slider sldAnzahlkarten
Height = 615
Left = 240
TabIndex = 5
Top = 360
Width = 3255
_ExtentX = 5741
_ExtentY = 1085
_Version = 393216
Enabled = 0 'False
LargeChange = 1
Min = 1
SelStart = 1
Value = 1
End
Begin VB.Label lblgewaehlterkarte
Caption = "----"
Height = 375
Left = 3600
TabIndex = 4
Top = 360
Width = 375
End
End
Begin VB.CommandButton cmdInitAll
Caption = "Initialisieren"
Height = 495
Left = 2640
TabIndex = 2
Top = 1920
Width = 2295
End
Begin MSCommLib.MSComm MSComm1
Left = 4440
Top = -120
_ExtentX = 1005
_ExtentY = 1005
_Version = 393216
DTREnable = -1 'True
End
Begin VB.Label Label1
Caption = "Statusmeldung:"
BeginProperty Font
Name = "MS Sans Serif"
Size = 9.75
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 120
TabIndex = 1
Top = 120
Width = 1695
End
Begin VB.Label lblFehlerString
BeginProperty Font
Name = "MS Sans Serif"
Size = 9.75
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 735
Left = 120
TabIndex = 0
Top = 600
Width = 4815
End
End
Attribute VB_Name = "fmmain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'############################################################################### #########################
'Autor: CHA
'Funktion: Beispielprogramm zur Steuerung der seriellen Relaiskarte von Conrad
'History:
'April 2006: Erstentwicklung
'Oktober 2006: Wartezeiten mit Timer implementiert
'############################################################################### #######################

Option Explicit 'dont write spaghetti code define each var
Private OnBits(0 To 31) As Long
Const wartezeit = 0.05
'############################################################################### ##########################
'checkboxzustand wird gesendet
Private Sub chkrelais_Click(Index As Integer)
Dim wartezeit, FehlerNr As Long
Dim FehlerString As String
Dim instring As String
Dim Portzustand As Byte
Dim AnzahlRelaiskarten As Long
Dim Comport As Byte

Dim i, byDigiAus As Byte
byDigiAus = 0

For i = 0 To 7
If chkrelais(i).Value = 1 Then byDigiAus = byDigiAus + 2 ^ i
Next i

FehlerNr = ConradRelais_Setup(sldcom.Value, 1, AnzahlRelaiskarten)

Debug.Print "Anzahl der relaiskarten="; AnzahlRelaiskarten
If (FehlerNr <> 0) Then GoTo Fehlerbehandlung

wait (wartezeit)

FehlerNr = ConradRelais_SetPort(sldcom.Value, sldAnzahlkarten.Value, byDigiAus)
If (FehlerNr <> 0) Then GoTo Fehlerbehandlung

wait (wartezeit)

FehlerNr = ConradRelais_GetPort(sldcom.Value, sldAnzahlkarten.Value, Portzustand)

If (FehlerNr <> 0) Then GoTo Fehlerbehandlung

If (Portzustand <> byDigiAus) Then
FehlerNr = 4
GoTo Fehlerbehandlung
End If

If MSComm1.PortOpen = True Then MSComm1.PortOpen = False

Exit Sub 'kein Fehler aufgetreten sub vor Fehlerbehandlung beenden
Fehlerbehandlung:
FehlerString = FehlerNr2FehlerString(FehlerNr)

lblFehlerString.Caption = FehlerString
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
End Sub
'############################################################################### ##########################
Private Sub cmdInitAll_Click()
Dim FehlerNr As Long
Dim instring As String
Dim wartezeit As Long
Dim AnzahlRelaiskarten As Long
Dim i As Long
Dim Comport As Byte
Dim FehlerString As String

On Error GoTo Fehlerbehandlung

FehlerNr = 5

If MSComm1.PortOpen = False Then

MSComm1.CommPort = sldcom.Value

MSComm1.Settings = "19200,N,8,1"

MSComm1.InputLen = 0 'ein frame besteht aus 4 bytes

MSComm1.PortOpen = True
End If


FehlerNr = ConradRelais_Setup(sldcom.Value, 1, AnzahlRelaiskarten)
If (FehlerNr <> 0) Then GoTo Fehlerbehandlung


If (AnzahlRelaiskarten > 0) Then
sldAnzahlkarten.Enabled = True
sldAnzahlkarten.Min = 1

If AnzahlRelaiskarten = 1 Then
sldAnzahlkarten.Max = 2 'sldAnzahlkarten.Max darf nicht
MsgBox ("Nur eine Relaiskarte gefunden->Keine Auswahl möglich")
sldAnzahlkarten.Enabled = False
Else
sldAnzahlkarten.Max = AnzahlRelaiskarten
End If

lblgewaehlterkarte.Caption = CStr(sldAnzahlkarten.Value)

For i = chkrelais.LBound To chkrelais.UBound
chkrelais.Item(i).Enabled = True
Next i

End If

If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
FehlerNr = 0
lblFehlerString.Caption = "Alles OK"
Exit Sub 'kein Fehler aufgetreten sub vor Fehlerbehandlung beenden
Fehlerbehandlung:
FehlerString = FehlerNr2FehlerString(FehlerNr)
lblFehlerString.Caption = FehlerString
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
End Sub
'############################################################################### ##########################

'############################################################################### ##########################
'initialisieren der relaisplatinen und ermitteln der Anzahl der relaisplatinen
'
Private Function ConradRelais_Setup(Comport, KartenAdresse As Byte, AnzahlRelaiskarten) As Long
Dim instring As String
Dim byte1, byte2, byte3, byte4, xorbyte As Byte
Dim laenge As Long
Dim start, timestamp As Double
Dim FehlerNr As Long
Dim bytefeld() As Byte

byte1 = 1 'CMD
byte2 = KartenAdresse 'Adr
byte3 = 255 '
byte4 = byte1 Xor byte2 Xor byte3

If MSComm1.PortOpen = False Then
MSComm1.CommPort = Comport
MSComm1.Settings = "19200,N,8,1"
MSComm1.InputLen = 0 'ein frame besteht aus 4 bytes
MSComm1.PortOpen = True
End If

MSComm1.Output = Chr(byte1) & Chr(byte2) + Chr(byte3) + Chr(byte4) 'senden

Do
start = Timer 'aktuellen timerwert einfrieren
Do
DoEvents
If Timer > start + 1 Then
FehlerNr = 1
GoTo Fehlerbehandlung
End If
DoEvents
Debug.Print "davor"; MSComm1.InBufferCount
Loop Until MSComm1.InBufferCount >= 4
instring = instring + MSComm1.Input 'frame einlesen
Debug.Print "danach"; MSComm1.InBufferCount
wait wartezeit 'zeit um zeichen zu empfangen
Loop Until MSComm1.InBufferCount = 0

Debug.Print MSComm1.InBufferCount

byte1 = Asc(Mid(instring, 1, 1))
byte2 = Asc(Mid(instring, 2, 1))
byte3 = Asc(Mid(instring, 3, 1))
byte4 = Asc(Mid(instring, 4, 1))
xorbyte = byte1 Xor byte2 Xor byte3

If byte1 = 255 Then
FehlerNr = 3
GoTo Fehlerbehandlung
End If

If xorbyte <> byte4 Then
FehlerNr = 2
GoTo Fehlerbehandlung
End If

AnzahlRelaiskarten = Len(instring) / 4 - 1
ConradRelais_Setup = 0 'wenn alles Fehlerfrei funktioniert hat
Exit Function 'ende wenn kein fehler aufgetreten ist
Fehlerbehandlung:
ConradRelais_Setup = FehlerNr

End Function
'############################################################################### ##########################
'wartezeit in sekunden
Private Sub wait_seconds(ZeitinSekunden As Byte)
Dim start As Double
start = Timer
Do
DoEvents
Loop Until Timer >= start + ZeitinSekunden
End Sub
'############################################################################### ##########################
'wartezeit-ist zwischen einigen operationen der relaiskarte notwendig
Private Sub wait(Zeit As Single)
Dim start As Single
start = Timer
Do
DoEvents
Loop Until Timer > (start + Zeit)
End Sub
'############################################################################### ##########################
'SETPORT funktion daten 0 bis 255
Private Function ConradRelais_SetPort(Comport, KartenAdresse, Daten As Byte) As Long
Dim byte1, byte2, byte3, byte4, xorbyte As Byte
Dim instring As String
Dim FehlerNr As Long
Dim start As Double

byte1 = 3 'CMD Setport
byte2 = KartenAdresse 'Adr
byte3 = Daten '
byte4 = byte1 Xor byte2 Xor byte3

If MSComm1.PortOpen = False Then

MSComm1.CommPort = Comport

MSComm1.Settings = "19200,N,8,1"

MSComm1.InputLen = 0 'ein frame besteht aus 4 bytes

MSComm1.PortOpen = True
End If

MSComm1.Output = Chr(byte1) & Chr(byte2) + Chr(byte3) + Chr(byte4) 'senden

start = Timer
Do
DoEvents
If Timer > start + 2 Then 'timeout
FehlerNr = 1
GoTo Fehlerbehandlung
End If
Loop Until MSComm1.InBufferCount >= 4

instring = MSComm1.Input

byte1 = Asc(Mid(instring, 1, 1))
byte2 = Asc(Mid(instring, 2, 1))
byte3 = Asc(Mid(instring, 3, 1))
byte4 = Asc(Mid(instring, 4, 1))
xorbyte = byte1 Xor byte2 Xor byte3 'Prüfsumme errechnen

If byte1 = 255 Then
FehlerNr = 3
GoTo Fehlerbehandlung
End If

If xorbyte <> byte4 Then
FehlerNr = 2
GoTo Fehlerbehandlung
End If

Exit Function 'ende wenn kein fehler aufgetreten ist
Fehlerbehandlung: 'Sprungmarke
ConradRelais_SetPort = FehlerNr

End Function
'############################################################################### ##########################
'zugehörigen FehlerString zur FehlerNr ermitteln
Private Function FehlerNr2FehlerString(FehlerNr As Long) As String
Select Case FehlerNr
Case 1
FehlerNr2FehlerString = "Kommunikationstimeout-Ist die Relaiskarte richtig angschlossen?"

Case 2
FehlerNr2FehlerString = "Übertragungsfehler Übertragung Relaiskarte->PC entdeckt-versuchs nochmal"

Case 3
FehlerNr2FehlerString = "Übertragungsfehler Übertragung PC->Relaiskarte entdeckt-versuchs nochmal"
Case 4
FehlerNr2FehlerString = "Übertragungsfehler Übertragung PC->Relaiskarte entdeckt-versuchs nochmal"
Case 5
FehlerNr2FehlerString = "Probleme mit Comport- versuche einen anderen "
Case Else
FehlerNr2FehlerString = "Fehler kann nicht zugeordnet werden"
End Select

End Function
'############################################################################### ##########################
'GETPORT
Private Function ConradRelais_GetPort(Comport, KartenAdresse, ByRef EmpfangsDaten As Byte) As Long
Dim byte1, byte2, byte3, byte4, xorbyte As Byte
Dim instring As String
Dim FehlerNr As Long
Dim start As Double

byte1 = 2 'CMD Setport
byte2 = KartenAdresse 'Adr
byte3 = EmpfangsDaten '
byte4 = byte1 Xor byte2 Xor byte3

On Error GoTo Fehlerbehandlung

If MSComm1.PortOpen = False Then

MSComm1.CommPort = Comport

MSComm1.Settings = "19200,N,8,1"

MSComm1.InputLen = 0 'ein frame besteht aus 4 bytes

MSComm1.PortOpen = True
End If

FehlerNr = 5

MSComm1.Settings = "19200,N,8,1"

MSComm1.InputLen = 0

FehlerNr = 5

MSComm1.Output = Chr(byte1) & Chr(byte2) + Chr(byte3) + Chr(byte4) 'senden

start = Timer
Do
DoEvents
If Timer > start + 2 Then 'timeout
FehlerNr = 1
GoTo Fehlerbehandlung
End If
Loop Until MSComm1.InBufferCount >= 4

instring = MSComm1.Input

byte1 = Asc(Mid(instring, 1, 1))
byte2 = Asc(Mid(instring, 2, 1))
byte3 = Asc(Mid(instring, 3, 1))
byte4 = Asc(Mid(instring, 4, 1))
xorbyte = byte1 Xor byte2 Xor byte3 'Prüfsumme errechnen

If byte1 = 255 Then 'PIC controller auf Relaiskarte hat übertragungsfehler erkannt
FehlerNr = 3
GoTo Fehlerbehandlung
End If

If xorbyte <> byte4 Then 'Übertragungsfehler erkannt
FehlerNr = 2
GoTo Fehlerbehandlung
End If

EmpfangsDaten = byte3 'rückgabe der empfangenen daten= Portzustandsbyte

If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
FehlerNr = 0
Exit Function 'ende wenn kein fehler aufgetreten ist
Fehlerbehandlung: 'Sprungmarke
ConradRelais_GetPort = FehlerNr
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
FehlerNr = 0
End Function

'############################################################################### ##########################
Private Sub Form_Load()
'Comport = 1
End Sub
'############################################################################### ##########################
Private Sub sldAnzahlkarten_Change()
Dim FehlerNr As Long
Dim Portzustand As Byte
Dim i As Long

FehlerNr = ConradRelais_GetPort(sldcom.Value, sldAnzahlkarten.Value, Portzustand)

' For i = 0 To 7
' 'Portzustand
' Call RShiftLong(Portzustand, i)
' If Portzustand = 1 Then chkrelais(i).Value = 1
' Next i


lblgewaehlterkarte.Caption = CStr(sldAnzahlkarten.Value)


End Sub
'############################################################################### ##########################
Private Sub sldAnzahlkarten_Click()

End Sub
'############################################################################### ##########################
Private Sub sldcom_Change()
lblcomport.Caption = CStr(sldcom.Value)
End Sub

Public Function RShiftLong(ByVal Value As Long, ByVal Shift As Integer) As Long
Dim hi As Long
MakeOnBits
If (Value And &H80000000) Then hi = &H40000000

RShiftLong = (Value And &H7FFFFFFE) \ (2 ^ Shift)
RShiftLong = (RShiftLong Or (hi \ (2 ^ (Shift - 1))))
End Function

Private Sub MakeOnBits()
Dim j As Integer, v As Long
For j = 0 To 30
v = v + (2 ^ j)
OnBits(j) = v
Next j
OnBits(j) = v + &H80000000
End Sub

Gast
2008-05-30, 18:36:48
Konvertierung von VB in VB.net (http://msdn.microsoft.com/de-de/library/bb979547.aspx#ID0EJBAC)

Upgrade-Wizard: http://msdn.microsoft.com/en-us/library/2s9eas74(VS.80).aspx

Win-Api anstatt Mscomm: http://msdn.microsoft.com/de-de/library/bb979092.aspx

tsaG
2008-06-01, 01:17:56
Hmm, hab mir jetzt vorgenommen sowas selber zu Programmieren..

nur steig ich da nicht ganz hinter, ich möchte jetzt bspw einfach relais 1 anziehen lassen. Mit welchem befehl? o0 310 ? (welche adresse hat denn platine 1?)

das einfachste ist ja quasi das hier

SerialPort1.Open()
SerialPort1.Write(312)
SerialPort1.Close()

Es tut sich aber nichts. Nagut, das hab ich eigentlich auch nicht wirklich erwartet, es geht ja meist nicht so einfach (wär ja zu schön gewesen ^^)

hier ist die info wie die Platine funktioniert (Seite 6~): klick (http://www.produktinfo.conrad.com/datenblaetter/950000-974999/967720-an-01-de-Relaisplatine_8fach_seriell.pdf)

wäre nett wenn jemand mir ein beispiel posten könnte was man nun eigentlich an den seriellen port senden muss, ich steig da halt nochnicht ganz hinter :D

BTW: das hat nichtsmehr oben mit dem Code zutun.

robobimbo
2008-06-02, 11:28:07
Wenn ich die Anleitung richtig interpretiere - dann besteh ein Befehl an die Karte aus einer Folge (Frame) von 4 Bytes die hintereinander gesendet werden.

Das vierte Bit schein so eine Art primitive Checksumme (XOR) über die drei vorangehenden Bytes zu sein.

Die Kommandos sind auf der Seite 6 aufgelistet (0-5) sowie die jeweiligen Antworten dazu

tsaG ausser haus
2008-06-02, 12:16:48
Ja, aber ich verstehe halt nochnicht genau wie man das alles packt und dann abschickt o0



dim Zeichenfolge(3) as Byte

Zeichenfolge(0) = "3"
Zeichenfolge(1) = "0"
Zeichenfolge(2) = "1"

Zeichenfolge(3) = Zeichenfolge(0) XOR Zeichenfolge(1) XOR Zeichenfolge(2)

serialport.open
serialport.write(Zeichenfolge, 0, 1, 2, 3)
serialport.close

Ich versteh halt nicht wirklich was man jetzt wirklich hin schicken soll und besonders in welchem Format.

robobimbo
2008-06-03, 11:30:04
Ja, aber ich verstehe halt nochnicht genau wie man das alles packt und dann abschickt o0



dim Zeichenfolge(3) as Byte

Zeichenfolge(0) = "3"
Zeichenfolge(1) = "0"
Zeichenfolge(2) = "1"

Zeichenfolge(3) = Zeichenfolge(0) XOR Zeichenfolge(1) XOR Zeichenfolge(2)

serialport.open
serialport.write(Zeichenfolge, 0, 1, 2, 3)
serialport.close

Ich versteh halt nicht wirklich was man jetzt wirklich hin schicken soll und besonders in welchem Format.

Die Doku der serialport.write Mehtode aus dem MSDN hilft Dir weiter: http://msdn.microsoft.com/en-us/library/ms143551.aspx

Dein Kommando müsste richtigerweise lauten:
serialport.write(Zeichenfolge, 0, 4)

Zeichenfolge - das Array in dem deine zu sendenden Werte stehen
Offset - ab wo er in dem Array beginnen soll
Count - wieviele Elemente er schreiben soll, in deinem Fall 4

tsaG ausser haus
2008-06-03, 17:27:29
Und dann sollte es funktionieren? Das Problem war nicht wirklich wie ich an die Relaiskarte sende, sondern vielmehr was ich überhaupt sende :D Weil ich aus der Anleitung halt einfach nicht schlau werde ^^

robobimbo
2008-06-04, 14:29:09
Jede Relaiskarte die an deinem System hängt wird über eine eindeutige Adresse angesprochen, wenn du Pakete an die Adresse 0 schickst, sendest Du einen Broadcast und alle Karte führen den Befehl aus.

Es gibt eh nur 5 Kommandos (Seite 6 unten)

Je nach dem welches Kommando du senden willst, hat somit das erste Byte den Wert 0 - 5
Jedes der Kommandos braucht im 2ten Byte die Angae der Adresse - damit sich auch die richtige Platine angesprochen fühlt
Nur bei dem Befehlen mit der Nr. 3 und Nr. 5 ist auch das dritte Byte relevant, bei den anderen Befehlen isses wurscht

Bei den Daten die du bekommst ist es ganz ähnlich:
Das erste Byte sagt dir, auf welches deiner Kommandos Du die Antwort bekommst (250-255)
Im zweiten Befehl bekommst Du die Adresse von der Karte die Dir was schickt
Und im dritten Byte sind dann bei zwei Befehlen wieder Daten zu finden

Das vierte Byte ist in sowohl beim Senden als auch beim Empfangen die XOR Checksumme

tsaG
2008-06-04, 18:29:35
?

Das ist die antwort die ich bekomme :(

mit diesem Code

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Zeichenfolge(3) As Byte
Dim IncommingData As String = SerialPort1.ReadExisting


Zeichenfolge(0) = "3"
Zeichenfolge(1) = "0"
Zeichenfolge(2) = "1"

Zeichenfolge(3) = Zeichenfolge(0) Xor Zeichenfolge(1) Xor Zeichenfolge(2)



SerialPort1.Write(Zeichenfolge, 0, 4)

TextBox1.Text = IncommingData
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
SerialPort1.Open()
End Sub
End Class


Ich probier mal noch weiter rum, wenn jemand Rat weiss, immer her damit.

PS: habe das Port öffnen auf nen anderen Button gelegt, weil es sonst garnicht funktioniert hat

Gast
2008-06-04, 18:35:02
Wenn du Probleme mit der GUI hast, dann mach erstmaln simples write in der Konsole und schau, was sich muckt.

tsaG
2008-06-04, 19:53:20
So, ich habe es hinbekommen :D

Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With SerialPort1
.PortName = "COM1"
.BaudRate = "19200"
.Parity = System.IO.Ports.Parity.None
.DataBits = "8"
.StopBits = "1"
End With
End Sub
Public Function senden(ByVal box)
SerialPort1.Open()
Dim Zeichenfolge(3) As Byte
Dim IncommingData As String = SerialPort1.ReadExisting


Zeichenfolge(0) = "3"
Zeichenfolge(1) = "0"
Zeichenfolge(2) = box

Zeichenfolge(3) = Zeichenfolge(0) Xor Zeichenfolge(1) Xor Zeichenfolge(2)



SerialPort1.Write(Zeichenfolge, 0, 4)
SerialPort1.Close()

End Function

Private Sub r1_Checked(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles r1.CheckedChanged
senden(TextBox1.Text)
End Sub
End Class

So, nun nächstes "Problem". Die Relais Ausgänge werden nicht direkt angesteuert, sondern nach folgendem Schema (versuchs mal zu beschreiben).

Byte 2:
0 = Alle Relais aus
1 = Nur 1. Relais an
2 = Nur 2. Relais an
3 = 1. und 2. an
4 = 3. an
5 = 1 und 3 an
6 = 2 und 3 an
7 = 1, 2 und 3 an
8 = 4 an
9 = 1 und 4 an
10 = 2 und 4 an
11 = 1, 2 und 4 an
12 = 3 und 4 an
13 = 1, 3 und 4 an

etc... kann man da irgendeinen Algorythmus einbauen womit er automatisch die Zahl berechnet?

Wollte das ganze mit Check Boxen machen, wie in dem beispiel Programm oben.

Also quasi, wenn Box 1 und 2 markiert ist der Wert 3
Wenn dann noch box 3 hinzu kommt ist der Wert 7....

Hab da noch keine Mathe Formel entdecken können... ^^

EDIT:
Hab das hier im alten Code gefunden und konnte es nicht zuordnen, kann es sein dass es dafür genutzt wurde?

Public Function RShiftLong(ByVal Value As Long, ByVal Shift As Integer) As Long
Dim hi As Long
MakeOnBits
If (Value And &H80000000) Then hi = &H40000000

RShiftLong = (Value And &H7FFFFFFE) \ (2 ^ Shift)
RShiftLong = (RShiftLong Or (hi \ (2 ^ (Shift - 1))))
End Function

Private Sub MakeOnBits()
Dim j As Integer, v As Long
For j = 0 To 30
v = v + (2 ^ j)
OnBits(j) = v
Next j
OnBits(j) = v + &H80000000
End Sub

Jedoch weiss ich (wiedermal) nicht wie man das benutzt xD (wobei der auch noch an vb.net angepasst werden muss)

robobimbo
2008-06-05, 11:15:57
Byte 2:
0 = Alle Relais aus
1 = Nur 1. Relais an
2 = Nur 2. Relais an
3 = 1. und 2. an
4 = 3. an
5 = 1 und 3 an
6 = 2 und 3 an
7 = 1, 2 und 3 an
8 = 4 an
9 = 1 und 4 an
10 = 2 und 4 an
11 = 1, 2 und 4 an
12 = 3 und 4 an
13 = 1, 3 und 4 an

etc... kann man da irgendeinen Algorythmus einbauen womit er automatisch die Zahl berechnet?


Stell dir das ganze mal als Bits vor, also als Zahl mit der Basis 2 - dann sollte eigentlich der Groschen fallen

00000000 = 0
00000001 = 1
00000010 = 2
00000011 = 3
00000100 = 4
00000101 = 5
00000110 = 6
00000111 = 7
00001000 = 8
...
11111111 = 255

Mit 1+4+8 würdest Du Bit 0, Bit 2 und Bit 3 setzen
Mit 1+2 nur Bit 0 und Bit 1

tsaG
2008-10-01, 13:09:48
Okay, hab es nun folgendermassen gemacht

Dim Daten As Int32
For i As Int32 = 1 To 8
If CType(Me.Controls("CheckBox" & i.ToString), CheckBox).Checked Then
Daten += 1 << i - 1
End If
Next

Das wird immer ausgelöst wenn jemand einen Haken setzt.


AddHandler CheckBox1.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox2.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox3.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox4.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox5.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox6.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox7.CheckStateChanged, AddressOf CheckedChanged
AddHandler CheckBox8.CheckStateChanged, AddressOf CheckedChanged



Funktioniert auch nun 1a. Da man jetzt auch den Status der Karte abfragen kann müsste man das ganze auch wieder zerlegen können, in Status für 1 oder 0. Nur die Frage... wie? :D

Gast
2010-01-17, 12:00:41
Hi,

Hallo, habe auch ein ähnliches Problem. Der obige Block von tsaG hat mir schon richtig geholfen das Datenpaket zu bilden, nun habe ich jedoch noch ein Problem. Wie kann ich den Seriellen Port richtig auselen?

Habe es wie folgt gemacht (Code ist inkl Paket bilden und senden)

Dim Daten As Int32
For i As Int32 = 1 To 8
If CType(Me.Controls("CheckBox" & i.ToString), CheckBox).Checked Then
Daten += 1 << i - 1
End If
Next

Dim Zeichenfolge(3) As Byte



Zeichenfolge(0) = "3"
Zeichenfolge(1) = "0"
Zeichenfolge(2) = Daten

Zeichenfolge(3) = Zeichenfolge(0) Xor Zeichenfolge(1) Xor Zeichenfolge(2)


SerialPort1.Write(Zeichenfolge, 0, 4)
TextBox1.Text = TextBox1.Text + SerialPort1.ReadExisting

Wenn ich doch halt mit "TextBox1.Text = TextBox1.Text + SerialPort1.ReadExisting" den Port auslese, bekomme ich nur ein Fragezeichen. In der Anleitung Steht "JEdes Kommando und jede Antwort besteht jeweils aus einer Folge von 4Bytes"

http://www2.produktinfo.conrad.com/datenblaetter/175000-199999/197720-an-01-ml-8FACH_RELAISKARTE_24V_7A_de_en_fr_nl.pdf (Seite 12).

weiss jemand bescheid? :)

robobimbo
2010-01-18, 19:52:15
Versuchst mit SerialPort1.Read() und SerialPort1.BytesToRead

Das zweite sagt dir wieviel Bytes anstehen und mit dem ersten liest du dann die Bytes ein - siehe auch MSDN http://msdn.microsoft.com/de-de/library/ms143549(VS.80).aspx

War jetzt aber nicht so schwer das mit Google zu finden...

tsaG
2011-04-28, 21:59:13
So, wollte den Thread noch einmal ausgraben.

Ich habe jetzt die Bytes. Wie kann ich diese möglichst einfach in bits umwandeln?

Hintergrund: Der Status der Relais wird ausgelesen bspw. wenn alle an sind:
11111111 = 255
das ganze wird dann übertragen. Am anderen ende möchte ich das ganz wieder entschlüsseln.. wie mach ich das am besten? :)

EDIT: Hat sich eigentlich erledigt da ich es nicht mehr benötige. Wäre aber trotzdem ganz interessant die Lösung zu erfahren