Lenz en Visual Basic

Gestart door h.evering, 17 februari 2008, 10:11:05 AM

INFO

Hans,

Op deze manier zal het ook niet werken.
citaat:
Private Sub LI101F_OnComm()
If LI101F.CommEvent = comEvReceive Then
Text1.Text = LI101F.Input ' Get data
End If
End Sub



Je hebt inputlen op 1 staan, dus er komt maar 1 teken binnen, je zult dus zoals ik je al liet zien dit via de inbuffercount en een while .. wend moeten oplossen. Om iedere keer 1 teken uit de buffer te lezen en te plakken aan de nog te verwerken string met inkomende informatie.
Inputlen = 1 is de juiste instelling.


Alleen de waarheid ligt in het midden.

eve

Wat INFO aangeeft is juist. Ik zat er al op te wachten.
INFO beschrijft de procedure die te volgen is als je niet weet hoeveel tekens er gaan binnenkomen op een vraag.

Mijn systeem (Rautenhaus) antwoordt steeds met 2 tekens zodat InputLen op 2 staat. Een tragere While...wend langs Inbuffercount heb ik dus niet nodig.

Geeft de LENZ-centrale ook steeds een vast aantal tekens terug ?

Laten we Hans nu niet laten lopen als hij nog niet kan gaan.

Erik

Flip2

Klopt Info ik heb het nog eens nagekeken .Dit is stof van mijn eerste "Lenz jaar " en dat is 12j geleden.
Ik heb versie 2.3.  

Het eerste is altijd de Header  hier tussen de bytes die verschillen naar gelang het geen binnen komt of buiten gaat en als laatste een Prufbyte (XOR).Aan de waarde van de Header kan men zien of het bv om een lokbevel gaat of bv een terugmelding.Bij een antwoord op een bevel is (B1)de header 1 geloof ik. De inkomende informatie zijn characters een string dus.
Deze moeten ??n voor ??n ingelezen worden en dan omgezet naar decimale waarde. Vb  is header (B1) 66 dan gaat het om een terugmelding de volgende bytes bepalen adres en stand van de wissel of bezette sporen van een terugmeld module. Ik spreek hier over inkomende strings.

Flip2

INFO

Flip, dan heb jij wel een hele speciale versie. Het aantal tekens is onbekend, je weet namelijk niet wat het systeem gaat zenden.
Alleen de waarheid ligt in het midden.

INFO

Hans,

Maak een procedure voor het zenden.

maak een algemene array aan om je zend info in te plaatsen, en maak een algemene array aan om je te ontvangen string in te plaatsen.

Public znd(20) as integer
Public inbuf(50) as integer
Zijn beide groot genoeg en zullen nooit helemaal gevuld worden.



Public Sub Zend()
If Programmer.mnu_lenz.Checked And Programmer.Port.PortOpen Then
   With Programmer.Port
       If Not .PortOpen Then Exit Sub
       X = 1 + (Znd(1) And 15): Znd(20) = 0: Zenden = ""
       'In Znd(1) staat altijd de Header, en de Header bepaald het antal tekens welke volgen plus de controle.
       For i = 1 To X
           Znd(20) = Znd(20) Xor Znd(i)
           Zenden = Zenden + Chr(Znd(i))
       Next
?n Znd(20) staat de XOR van de te verzenden tekens.
       Zenden = Zenden + Chr(Znd(20))
       Temp = Zenden
       
       If LenzLiUSB Then
           .Output = Chr(&HFF) + Chr(&HFE) + Zenden
       ElseIf LenzRoco Then
           'geheim
       Else
           .Output = Zenden
       End If
   End With
End If
End Sub

Vanaf een andere plaats zend je de opdrachten b.v. het opvragen van de versie of iets anders.

Dus i.p.v. dit LI101F.Output = Chr(33) & Chr(33) & Chr(0), doe je dit

znd(1)= 33: znd(2) = 33 : Zend


Hoe je de inkomende string eventueel kunt verwerken.

Public Sub Lezenlenz(buffer)

''Of is het Je LenzLezen?
On Error Resume Next

If Programmer.mnu_lenz.Checked Then
Dim inbyte As String
Dim tel As Integer
HeaderFout = False


bezet$ = buffer

'If DBug Then FrmLenzLog.TxtLenzLog = FrmLenzLog.TxtLenzLog & bezet$ & vbCrLf

Do

tel = 0
Inbuf(tel) = 0
melding$ = ""
Do

 If bezet$ = "" Then Exit Sub
 
  Inbuf(tel) = Asc(bezet$)
  bezet$ = Mid$(bezet$, 2)
 
  ' Controle op geldige HEADER
   'Check the header

  Select Case Inbuf(0)
    Case 1, 2, 33, 97, 98, 99, 129, 131, 132, 163, 164, 197, 198, 225, 226, 227, 228, 229, 230, 242
    Case &HFF, &HFE
       tel = -1
    Case 66 To 78
    Case Else
    Inbuf(0) = 0: HeaderFout = True: szData = bezet$: bezet$ = "": LenzPM_Status = -1: Exit Sub
  End Select
 

   melding$ = melding$ + Str(Inbuf(tel))

  tel = tel + 1
Loop Until 2 + (Inbuf(0) And 15) = tel Or bezet$ = ""

' Verwerken binnengekomen info


If 2 + (Inbuf(0) And 15) = tel Then
   szData = bezet$
   'Rest van de string onthouden, en via On_Comm eventueel laten aanvullen.
Else
   Exit Sub
End If

If DBug Then FrmLenzLog.TxtLenzLog = FrmLenzLog.TxtLenzLog & melding$ & vbCrLf

Select Case Inbuf(0)
  Case 66 To 78
    'Terugmelding              
   
   
   
  Case 97
   If Inbuf(0) = 97 And Inbuf(1) = 1 And Inbuf(2) = 96 Then
     
       show_Ev2 (" System is active")
       SysteemStart = False
       
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 0 And Inbuf(2) = 97 Then
       show_Ev2 (" Emergency off or SHORT")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 2 Then
    FrmPT.LblTask.Caption = (" Program Modus")
    LenzPM_Status = 0
    DoEvents
   End If
   If Inbuf(0) = 97 And Inbuf(1) = &H1F Then
   FrmPT.LblTask.Caption = (" PT is busy")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 18 Then
   FrmPT.LblTask.Caption = (" SHORT on ProgramTrack")
    LenzPM_Status = 3
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 17 Then
   FrmPT.LblTask.Caption = (" ProgramTrack available")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 19 Then
   FrmPT.LblTask.Caption = (" No answer from decoder, or no decoder on PT ")
    'FrmPT.Cmd_On
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 128 Then
    show_Ev2 (" Transmission Error")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 129 Then
    show_Ev2 (" Command Station Busy")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 130 Then
    show_Ev2 (" Command not available")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 163 Then
    show_Ev2 (" Loc taken over by LH100")
   End If
   If Inbuf(0) = 97 And Inbuf(1) = 164 Then
    show_Ev2 (" Loc taken over by LH100")
   End If


   Case 98
   
     If Inbuf(1) = 33 Then
      LenzVersie = (Inbuf(2)  16) * 10 + (Inbuf(2) And 15)
      Versie = LenzVersie / 10
      Programmer.LblMessage.Caption = " LZ100 SoftWare Versie " + Str$(Versie)
     End If
   
   If Inbuf(1) = 34 Then
       With LenzStatus
       If Sgn(Inbuf(3) And 2 ^ 0) Then
       .Bit0 = "Command station is in Emergency Stop"
       Else
       .Bit0 = "Command station power On"
       End If
       If Sgn(Inbuf(3) And 2 ^ 1) Then
       .Bit1 = "Command station is in Emergency Off"
       Else
       .Bit1 = "Command station power On"
       End If
       If Sgn(Inbuf(3) And 2 ^ 2) Then
       .Bit2 = "Command station Start mode =1 (automatic mode)"
       Else
       .Bit2 = "Command station Start mode = 0 (manual mode)"
       End If
       If Sgn(Inbuf(3) And 2 ^ 3) Then
       .Bit3 = "Command station is in service mode"
       Else
       .Bit3 = "Command station is in normal mode"
       End If
       If Sgn(Inbuf(3) And 2 ^ 6) Then
       .Bit6 = "The command station is performing a power up"
       Else
       .Bit6 = "Power is On"
       End If
       If Sgn(Inbuf(3) And 2 ^ 7) Then
       .Bit7 = "There was a RAM check error in the command station"
       Else
       .Bit7 = "RAM check OK"
       End If
       End With
       'Frm_LenzStatus.Show
   End If
   Case 2
     
      LiVersie = (Inbuf(1)  16) * 10 + (Inbuf(1) And 15)
      LiVersie = LiVersie / 10
      show_Ev2 " LI100 SoftWare Versie " & Str$(LiVersie) & "." & Str(Inbuf(2))
  Case 99
               If Inbuf(1) = 33 Then
                   LenzVersie = (Inbuf(2)  16) * 10 + (Inbuf(2) And 15)
                   Versie = LenzVersie / 10
                   Programmer.LblMessage.Caption = " LZ100 SoftWare Versie " + Str$(Versie)
                   show_Ev2 " Lenz Digital Plus ( SWVer. " + Str(Versie) + " )"
                   '
                   
                   '
                   If Sgn(Inbuf(3) And 2 ^ 0) Then
                       show_Ev2 " Lenz Digital Plus ( SWVer. " + Str(Versie) + " )" + " LZ100"
                   ElseIf Sgn(Inbuf(3) And 2 ^ 1) Then
                      show_Ev2 " Lenz Digital Plus ( SWVer. " + Str(Versie) + " )" + " LH200"
                       'LenzStatus.VersieLZ = StatusBar1.Panels(2).Text
                   ElseIf Sgn(Inbuf(3) And 2 ^ 2) Then
                       show_Ev2 " Lenz Digital Plus ( SWVer. " + Str(Versie) + " )" + " Compact"
                       'LenzStatus.VersieLZ = StatusBar1.Panels(2).Text
                   End If
                   
               End If
               If Inbuf(1) = 16 Or Inbuf(1) = 20 Then
               LenzPM_Status = 1
               
               'Antwoord programmeerrails
      End If
               '***************************************
               

  Case 129
    If Inbuf(0) = 129 And Inbuf(1) = 0 And Inbuf(2) = 129 Then
       show_Ev2 (" Emergency Stop")
    End If
  Case 131, 163
       'With lk(Inbuf(1))
           
       'End With
  Case 132, 164
       With lk(Inbuf(1))
           
       End With
       
  Case 227
       'Status report (XPressNet Only)
       
  Case 228
       'locomotive info normale lok (XpressNet Only)
       
       
  Case 242
       CurBaud = 0
       If Inbuf(1) = 2 Then
           Select Case Inbuf(2)
               Case 1: CurBaud = 19200
               Case 2: CurBaud = 38400
               Case 3: CurBaud = 57600
               Case 4: CurBaud = 115200
           End Select
           Programmer.LblStatus2.Caption = CurBaud
           Programmer.LblMessage2.Caption = " LI101F " & CurBaud & " bps"
       End If
  Case 1
    If Inbuf(0) = 1 And Inbuf(1) = 1 Then
       show_Ev (" Fout tussen PC en Interface")
    End If

    If Inbuf(0) = 1 And Inbuf(1) = 2 Then
        'show_Ev (" Fout tussen Interface en Centrale")
        show_Ev ("Error between Interface and Command station")
    End If

    If Inbuf(0) = 1 And Inbuf(1) = 3 Then
        'show_Ev (" Fout ONBEKEND")
        show_Ev ("Error Unknown")
    End If

    If Inbuf(0) = 1 And Inbuf(1) = 4 Then
       'show_Ev (" OK, de volgende gegevens verzenden")
       show_Ev ("Ok, send next data")
       FrmPT.LblTask.Caption = "Ok"
       
    End If

    If Inbuf(0) = 1 And Inbuf(1) = 5 Then
       'show_Ev (" Centrale Antwoord niet")
       show_Ev ("No answer from command station")
       
    End If
End Select

'ENZOVOORT

Loop Until bezet$ = ""

End If

End Sub


Alleen de waarheid ligt in het midden.

eve

citaat:
Geplaatst door ysbeer

Ik zelf gebruik ook pio kaarten (8255 met 48 uitgangen)echter programmeer ik met quick basic (geen Qbasic),
Quck basic heeft een compiler.


Dit kan even eenvoudig in Visual Basic, naar mijn mening eenvoudiger. Ik heb ook ooit Compiled DOS-Basic met PIO-kaarten gebruikt...
Ook Visual Basic wordt compiled.

citaat:
Geplaatst door ysbeer
Lenz programmeren gaat vrij simpel,tenminste in qb.


Gezien de praktisch gelijke syntax zie ik hier geen verschillen tov. Visual Basic.

citaat:
Geplaatst door ysbeer
qb heeft het voordel onder DOS te draaien en daar door veel stabieler te zijn dan VB.


Ik heb op een ervaringstijd van 8 jaar met VB6 geen problemen gehad.

citaat:
Geplaatst door ysbeer
Ook heeft QB meer functie die aansluiten bij besturings doeleinde,


Kan U daar een voorbeeld van geven ?

citaat:
Geplaatst door ysbeer
Aansturig moet wel via RS232 wat ik kan geen USB sturen.
wim



USB-drivers voor DOS bestaan. Een adapter USB-RS232 behandel je dan gewoon als een COM-port vanuit Quickbasic.

Erik

h.evering

Dat is een heleboel informatie. Dat moet ik wat nader bestuderen met het VB-Handboek erbij. Dat kost wat meer tijd. Ik meld me weer.
Groet
Hans
 

Flip2

Ik heb mijn eerste stappen in Qbasic gezet over 12j. Daarna begonnen met VB 4 toen 5 en nu de 6 onder XP sedert jaren al(Win 95 en win 98 ging even goed)
Wat INFO schrijft zal wel werken denk ik maar ik doe het totaal anders het principe van inlezen komt natuurlijk altijd terug. Het werkt bij mij al 8j zonder problemen. Ik ben begonnen met Qbasic te leren en dan VB met vallen en opstaan en altijd verbetert.Ik heb over 9j terug les gevolgd van VB5 vanalles geleerd maar niet hoe ik mijn treintjes moest sturen. De leraar kende daar ook niets van maar wist dat het "heel" moeilijk was.
Men vind ook weinig lektuur over hardware sturen met PC.
Welke gek stuurt er nu treinen met een PC???

Gr
Flip

INFO

citaat:
Geplaatst door Flip2

Wat INFO schrijft zal wel werken denk ik
Gr
Flip



Ja Flip, daar hoef je niet aan te twijfelen.

Alleen de waarheid ligt in het midden.

h.evering

Ik ben bezig met een nadere studie van het bericht van INFO.
Ik heb de procedure aangemaakt voor het zenden zoals beschreven. Ik loop aan tegen het feit dat ik een object nodig heb voor de volgende commandoregels:

If Programmer.mnu_lenz.Checked And Programmer.Port.PortOpen Then
With Programmer.Port
If Not .PortOpen Then Exit Sub

Kan ik daar nog wat uitleg bij krijgen ?
Groet en dank
Hans
 

INFO

Tja, wat zal ik daar nu eens opzeggen??

Programmer is de naam van het hoofdformulier.
mnu_lenz is een onderdeel van een pulldownmenu op dat formulier.
en Port is een andere naam voor MSCOMM1. welke ook op hetzelfde formulier staat.

Het programma waaruit dit afkomstig is vind je hier http://people.zeelandnet.nl/rosoft/PT.exe

http://i5.photobucket.com/albums/y200/xammax/image015.jpg
Alleen de waarheid ligt in het midden.

h.evering

Ik moet proberen het wat eenvoudiger te houden, anders kom ik er niet uit. De reacties hebben al veel nieuwe wetenschap opgeleverd over VB, maar nog niet genoeg om alles te snappen. Ik begrij in ieder geval ook hoe ik de commando's in de "befehlsbeschreibung van Lenz zal moeten gebruiken.
Maar ik heb 'm nog niet goed aan de praat, m'n LI101F.
Ik heb nu de volgende code staan:

Dim znd(20) As Integer
Dim inbuf(50) As Integer
Public Sub Zend()

x = 1 + (znd(1) And 15): znd(20) = 0: Zenden = ""

For i = 1 To x
znd(20) = znd(20) Xor znd(i)
Zenden = Zenden + Chr(znd(i))
Next

Zenden = Zenden + Chr(znd(20))
Temp = Zenden

LI101F.Output = Chr(&HFF) + Chr(&HFE) + Zenden

End Sub
Private Sub cmdClose_Click()

Unload Me

End Sub
Private Sub Command1_Click()

   znd(1) = 33: znd(2) = 33: Zend
   
End Sub
Private Sub Form_Load()

LI101F.CommPort = 2
LI101F.RThreshold = 1
LI101F.SThreshold = 1
LI101F.InputLen = 1
LI101F.InputMode = comInputModeBinary
LI101F.Settings = "19200,N,8,1"
LI101F.InBufferSize = 1024
LI101F.OutBufferSize = 512
LI101F.Handshaking = comNone
LI101F.NullDiscard = False
LI101F.EOFEnable = False
LI101F.DTREnable = False
LI101F.RTSEnable = False
LI101F.PortOpen = True
Timer1.Enabled = False

End Sub
Public Sub Lezenlenz(buffer)

Dim inbyte As String
Dim tel As Integer
bezet$ = buffer

tel = 0
inbuf(tel) = 0
melding$ = ""

inbuf(tel) = Asc(bezet$)
bezet$ = Mid$(bezet$, 2)

tel = tel + 1
Loop Until 2 + (inbuf(0) And 15) = tel Or bezet$ = ""

If 2 + (inbuf(0) And 15) = tel Then
szdata = bezet$
End If

End Sub


Hoe kom ik verder ????????

Groet en dank voor de genomen moeite
Hans
 

INFO

Hoe je nu verder moet staat reeds in Lezenlenz, of te wel het verwerken van de gegevens die je in de inbuf array hebt geplaatst.

Verder zul je de LI101F via een break procedure moeten opstarten om de juiste baudrate te kunnen instellen en of te kunnen veranderen.

Eigenlijk staat alles wat je nodig hebt om het te laten werken in het eerdere bericht.


Verder moet je in je procedure natuurlijk wel een controle op geldigheid uitvoeren, en de bij de LI101F de twee voorlopende tekens niet meenemen in de te verwerken info, dus die moet je weggooien.
Het staat er allemaal niet voor niets.

IF Tel < 1 then

Select Case Inbuf(0)

Case 1, 2, 33, 97, 98, 99, 129, 131, 132, 163, 164, 197, 198, 225, 226, 227, 228, 229, 230, 242

Case &HFF, &HFE
tel = -1

Case 66 To 78

Case Else
Inbuf(0) = 0: HeaderFout = True: szData = bezet$: bezet$ = "": LenzPM_Status = -1: Exit Sub

End Select

End If

Verder moet je ook de dubbele do..loop gebruiken, je moet namelijk wel de inkomende informatie scheiden en verwerken.

Verder mis ik de procedure On_Comm, hoe ontvang je nu de informatie??



Alleen de waarheid ligt in het midden.

eve

Hans,
Ik lees nog steeds met belangstelling mee. Vermits de code van INFO is, zal ik me niet moeien met het inhoudelijke ervan.

Toch een algemene opmerking op gebied van Visual Basic zelf . Je schrijft :
Public Sub Lezenlenz(buffer)

Dim inbyte As String
Dim tel As Integer


Het is beter om de "dim" regels vooraan in het algemene stuk van je programma te plaatsen. Zoals jij het schrijft zal VB telkens je Lezenlenz oproept inbyte en tel initialiseren : dat kost tijd.

Erik

INFO

Tijd is er meer dan genoeg, de PC en het programma gaan vele male sneller dan dat Lenz de gegevens kan verwerken.

Maar je hebt natuurlijk gelijk. De code is al 25 jaar geleden geschreven toendertijd in QB 4.5  en is met heel weinig aanpassingen over gezet in VB6.0.

Het werkt, en als iets werkt moet je er vanaf blijven is mijn ervaring.
Alleen de waarheid ligt in het midden.