Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Anfängerfragen zum Programmieren mit PureBasic.
alDo
Beiträge: 41
Registriert: 28.01.2010 16:50
Wohnort: Hannover

Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von alDo »

Moin, bin neu hier und hab ein kleines problem mit diesen Toggle-Buttons. Sobald ich einmal auf die Dinger raufklicke passiert erst ma gar nichts. Erst beim 4? mal oder so versinkt der Button.

Mein Ziel ist es durch den Tastendruck eine Message über den Serialport zu verschicken und so lange der Button getogglet ist diese in einem best. Zeitintervall immer wieder zu senden.

Hoffe ihr nehmt mir meinen Noob-Code nich so übel. Benutz PB erst seit 2 Wochen.

Code: Alles auswählen

; 
; PB-Version: 4.40


;##################### constants #####################

Enumeration 
;constants to specify the textgadgets
  #CAN_Message
  #RecBytesText
  #IDText
  #D0Text
  #D1Text
  #D2Text
  #D3Text
  #D4Text
  #D5Text
  #D6Text
  #D7Text
  #EM_STOPText
  #V1Text
  #BACKText
  #STOPText
  #FORText
  #ONText
  #OFFText
  #UPText
  #DOWNText
;constants to specify the stringgadgets
  #RecBytesString
  #IDString
  #D0String
  #D1String
  #D2String
  #D3String
  #D4String
  #D5String
  #D6String
  #D7String
  #EM_STOPString
  #V1String
  #BACKString
  #STOPString
  #FORString
  #ONString
  #OFFString
  #UPString
  #DOWNString
;constants to specify the buttongadgets
  #EM_STOPButton
  #V1Button
  #BACKButton
  #STOPButton
  #FORButton
  #ONButton
  #OFFButton
  #UPButton
  #DOWNButton
EndEnumeration

;##################### variable declaration #####################

;-byte variables:
Global Dim Sendbuffer.b(9)
Global Dim ReceiveBuffer.b(1024)
Global Dim ReceiveBufferOrg.b(1024)
Global Dim BIT.b(63)
Global Dim DataBuffer.b(19)
HighByte.b
LowByte.b

;-integer variables:
Global windowMain.i
Global Ergebnis.i
Global SerPort.i
Global val_flag.i
Global Zeiger.i

;-string variables:
Global COMPORT.s
Global recBytes.s
Global Identifier.s
Global Dim Identifier.s(2)
Global Dim DB.s(7)
Global Dim DBH.s(7)
Global Dim DBL.s(7)
Global Dim REM_BIT.s(8)
Global Dim colorBIT.s(7)

;##################### variable initialisation #####################

;-byte initialisation:

For n=0 To 26
  ReceiveBufferOrg(n) = 48                             ; fill original receive buffer with 0 (ascii)
Next

For n=0 To 26
  ReceiveBuffer(n) = 48                                ; fill receive buffer with 0 (ascii)
Next

;-string initialisation:

COMPORT = "COM4"                                       ; pick the comport which to be used

For n=0 To 2
  Identifier(n) = "0"                                  ; fill array Identifier with "0"
Next

Identifier = Identifier(0)+Identifier(1)+Identifier(2) ; set the identifier to "000"

For n=0 To 7
  DB(n) = "0"                                          ; fill array DB() with "0"
Next

For n=0 To 8
  REM_BIT(n) = "0"                                     ; fill array REM_BIT() with "0"
Next

;##################### procedures #####################

Procedure createWindow()
  ;window
  If windowMain = OpenWindow(#PB_Any,0,0,320,300,"Erste CAN-Message",#PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
    MessageRequester("ERROR!","Can't open Window!",#PB_Window_ScreenCentered|#PB_MessageRequester_Ok)
  EndIf
  Frame3DGadget(#CAN_Message,10,10,300,100,"CAN_MESSAGE")
  ; textgadgets for CAN_Message
  TextGadget(#RecBytesText,125,33,100,20,"Received Bytes:",#PB_Text_Center)
  TextGadget(#IDText, 15,60,30,20,"ID",#PB_Text_Center)
  TextGadget(#D0Text, 60,60,30,20,"D0",#PB_Text_Center)
  TextGadget(#D1Text, 90,60,30,20,"D1",#PB_Text_Center)
  TextGadget(#D2Text,120,60,30,20,"D2",#PB_Text_Center)
  TextGadget(#D3Text,150,60,30,20,"D3",#PB_Text_Center)
  TextGadget(#D4Text,180,60,30,20,"D4",#PB_Text_Center)
  TextGadget(#D5Text,210,60,30,20,"D5",#PB_Text_Center)  
  TextGadget(#D6Text,240,60,30,20,"D6",#PB_Text_Center)
  TextGadget(#D7Text,270,60,30,20,"D7",#PB_Text_Center)
  ; stringgadgets for CAN_Message
  StringGadget(#RecBytesString,225,33,75,20,recBytes,#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#IDString, 15,80,30,20,Identifier,#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D0String, 60,80,30,20,DB(0),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D1String, 90,80,30,20,DB(1),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D2String,120,80,30,20,DB(2),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D3String,150,80,30,20,DB(3),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D4String,180,80,30,20,DB(4),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D5String,210,80,30,20,DB(5),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D6String,240,80,30,20,DB(6),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#D7String,270,80,30,20,DB(7),#PB_Text_Center|#SS_SUNKEN)
  ; textgadgets for Remote Control
  TextGadget(#EM_STOPText,23,160,50,20,"EM.-STOP",#PB_Text_Center)
  ;TextGadget(#V1Text,110,160,30,20,"V1",#PB_Text_Center)
  TextGadget(#BACKText,30,240,30,20,"BACK",#PB_Text_Center)
  TextGadget(#STOPText,80,240,30,20,"STOP",#PB_Text_Center)
  TextGadget(#FORText,130,240,30,20,"FOR",#PB_Text_Center)
  TextGadget(#ONText,200,180,30,20,"ON",#PB_Text_Center)
  TextGadget(#OFFText,200,240,30,20,"OFF",#PB_Text_Center)
  TextGadget(#UPText,260,180,30,20,"UP",#PB_Text_Center)
  TextGadget(#DOWNText,257,240,35,20,"DOWN",#PB_Text_Center)
  ; stringgadgets for Remote Control
  StringGadget(#EM_STOPString,30,180,30,20,REM_BIT(0),#PB_Text_Center|#SS_SUNKEN)
  ;StringGadget(#V1String,110,180,30,20,REM_BIT(1),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#BACKString,30,260,30,20,REM_BIT(2),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#STOPString,80,260,30,20,REM_BIT(3),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#FORString,130,260,30,20,REM_BIT(4),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#ONString,200,200,30,20,REM_BIT(5),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#OFFString,200,260,30,20,REM_BIT(6),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#UPString,260,200,30,20,REM_BIT(7),#PB_Text_Center|#SS_SUNKEN)
  StringGadget(#DOWNString,260,260,30,20,REM_BIT(8),#PB_Text_Center|#SS_SUNKEN)
  ; buttongadgets for Remote Control
  ButtonGadget(#EM_STOPButton,30,200,30,10,"",#PB_Button_Toggle)
  ;ButtonGadget(#V1Button,110,200,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#BACKButton,30,280,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#STOPButton,80,280,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#FORButton,130,280,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#ONButton,200,220,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#OFFButton,200,280,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#UPButton,260,220,30,10,"",#PB_Button_Toggle)
  ButtonGadget(#DOWNButton,260,280,30,10,"",#PB_Button_Toggle)
EndProcedure
Procedure openCAN()
  WriteSerialPortData(SerPort,@SendBuffer(4),1)   ;open can channel
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR
EndProcedure
Procedure closeCAN()
  WriteSerialPortData(SerPort,@SendBuffer(6),1)   ;close can channel
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR
EndProcedure
Procedure readSerPort()
  Ergebnis = 0
  Ergebnis = AvailableSerialPortInput(SerPort)               ; remaining bytes in inout buffer
  ReadSerialPortData(SerPort,@ReceiveBufferOrg(0),Ergebnis)  ; read serial port
EndProcedure
Procedure initCAN()
  SerPort = OpenSerialPort(#PB_Any,COMPORT,9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,65535,65535)
  ; set commands
  SendBuffer(0)=86  ;"V" for version number
  SendBuffer(1)=13  ;CR  for carriage return
  SendBuffer(2)=83  ;"S" for setup the can bitrate
  SendBuffer(3)=53  ;"5" for 250k
  ;SendBuffer(3)=52  ;"4" for 125k
  SendBuffer(4)=79  ;"O" open the can channel
  SendBuffer(5)=70  ;"F" read status flags
  SendBuffer(6)=67  ;"C" close the can channel
  SendBuffer(7)=90  ;"Z" timestamp
  SendBuffer(8)=48  ;"0" off
  SendBuffer(9)=116 ;"t" transmit a standard CAN frame
  
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR  empty any 
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR  prior 
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR  command

  closeCAN()
  readSerPort()
   
  WriteSerialPortData(SerPort,@SendBuffer(0),1)   ;version?
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR
  readSerPort()
  
  WriteSerialPortData(SerPort,@SendBuffer(2),1)   ;setup
  WriteSerialPortData(SerPort,@SendBuffer(3),1)   ;can bitrate to 250k
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR
  readSerPort()
  
  WriteSerialPortData(SerPort,@SendBuffer(7),1)   ;timestamp
  WriteSerialPortData(SerPort,@SendBuffer(8),1)   ;off
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ;CR
  readSerPort()
  
  openCAN()
  readSerPort()
EndProcedure
Procedure convertAsciiToHalfbyte(Rec_Ascii.b,n.b)
  Select Rec_Ascii
    Case 48  ;HALFBYTE = $0
      BIT0 = 0
      BIT1 = 0
      BIT2 = 0
      BIT3 = 0
    Case 49  ;HALFBYTE = $1
      BIT0 = 1
      BIT1 = 0
      BIT2 = 0
      BIT3 = 0
    Case 50  ;HALFBYTE = $2
      BIT0 = 0
      BIT1 = 1
      BIT2 = 0
      BIT3 = 0
    Case 51  ;HALFBYTE = $3
      BIT0 = 1
      BIT1 = 1
      BIT2 = 0
      BIT3 = 0
    Case 52  ;HALFBYTE = $4
      BIT0 = 0
      BIT1 = 0
      BIT2 = 1
      BIT3 = 0
    Case 53  ;HALFBYTE = $5     
      BIT0 = 1
      BIT1 = 0
      BIT2 = 1
      BIT3 = 0
    Case 54  ;HALFBYTE = $6
      BIT0 = 0
      BIT1 = 1
      BIT2 = 1
      BIT3 = 0
    Case 55  ;HALFBYTE = $7
      BIT0 = 1
      BIT1 = 1
      BIT2 = 1
      BIT3 = 0
    Case 56  ;HALFBYTE = $8
      BIT0 = 0
      BIT1 = 0
      BIT2 = 0
      BIT3 = 1
    Case 57  ;HALFBYTE = $9
      BIT0 = 1
      BIT1 = 0
      BIT2 = 0
      BIT3 = 1
    Case 65  ;HALFBYTE = $A
      BIT0 = 0
      BIT1 = 1
      BIT2 = 0
      BIT3 = 1
    Case 66  ;HALFBYTE = $B
      BIT0 = 1
      BIT1 = 1
      BIT2 = 0
      BIT3 = 1
    Case 67  ;HALFBYTE = $C
      BIT0 = 0
      BIT1 = 0
      BIT2 = 1
      BIT3 = 1
    Case 68  ;HALFBYTE = $D
      BIT0 = 1
      BIT1 = 0
      BIT2 = 1
      BIT3 = 1    
    Case 69  ;HALFBYTE = $E
      BIT0 = 0
      BIT1 = 1
      BIT2 = 1
      BIT3 = 1
    Case 70  ;HALFBYTE = $F
      BIT0 = 1
      BIT1 = 1
      BIT2 = 1
      BIT3 = 1
  EndSelect

  BIT(n)   = BIT0   ; save first  bit (from right) in array BIT()
  BIT(n+1) = BIT1   ; save second bit (from right) in array BIT()
  BIT(n+2) = BIT2   ; save third  bit (from right) in array BIT()
  BIT(n+3) = BIT3   ; save fourth bit (from right) in array BIT()
EndProcedure
Procedure receiveCANMessage()
    
  SetGadgetText(#RecBytesString,Str(Ergebnis))                        ; number of received bytes
  
  If Ergebnis < 7                                                     ; filtering garbage
    val_flag = 0
    ProcedureReturn
  EndIf
  
  ReadSerialPortData(SerPort,@ReceiveBufferOrg(0),Ergebnis)           ; read complete receive buffer
  
  For n=0 To Ergebnis
    If ReceiveBufferOrg(n) = 116                                      ; search for 't' (begin of message)
      For i=0 To Ergebnis
        ReceiveBuffer(i) = ReceiveBufferOrg(i+n)                      ; write received message in receive buffer
          If ReceiveBufferOrg(i+n) = 13
            
            Identifier(0) = Chr(ReceiveBuffer(Zeiger + 1))            ; first  part of the identifier
            Identifier(1) = Chr(ReceiveBuffer(Zeiger + 2))            ; second part of the identifier
            Identifier(2) = Chr(ReceiveBuffer(Zeiger + 3))            ; third  part of the identifier
            Identifier    = Identifier(0)+Identifier(1)+Identifier(2) ; get identifier of received message
            
            ;MovPointer = ReceiveBuffer(Zeiger+m)                      ; pointer + offset to navigate through the receive buffer (less redundancy)
            
            For m=5 To 19 Step 2
              DBH((m-5)/2) = Chr(ReceiveBuffer(Zeiger+m))             ; store the high bytes in array DBH()
              convertAsciiToHalfbyte(ReceiveBuffer(Zeiger+m),(m-4)*4) ; converts the high bytes from ascii to halfbytes
            Next
            
            For m=6 To 20 Step 2
              DBL((m-6)/2) = Chr(ReceiveBuffer(Zeiger+m))             ; store the  low bytes in array DBL()
              convertAsciiToHalfbyte(ReceiveBuffer(Zeiger+m),(m-6)*4) ; converts the  low bytes from ascii to halfbytes
            Next
            
            For m=0 To 7
              DB(m) = DBH(m)+DBL(m)                                   ; 'merge' two halfbytes together and store in array DB()
            Next
            
            val_flag = 1
          EndIf
      Next
    EndIf
  Next
EndProcedure
Procedure CANTransmit()
  DataBuffer(0)=48                                ; first  part of the Identifier = 0
  DataBuffer(1)=48                                ; second part of the Identifier = 0
  DataBuffer(2)=70                                ; third  part of the Identifier = F
  ;DataBuffer(3)=56                                ; amount of bytes = 8
  DataBuffer(3)=49                                ; amount of bytes = 1

  WriteSerialPortData(SerPort,@SendBuffer(9),1)   ; t command (send)

  WriteSerialPortData(SerPort,@DataBuffer(0),1)   ; first  part of the Identifier "00F"
  WriteSerialPortData(SerPort,@DataBuffer(1),1)   ; second part of the Identifier "00F"
  WriteSerialPortData(SerPort,@DataBuffer(2),1)   ; third  part of the Identifier "00F"
  
  WriteSerialPortData(SerPort,@DataBuffer(3),1)   ; data length = 1 Byte
  
  WriteSerialPortData(SerPort,@DataBuffer(4),1)   ; high byte of the data byte
  WriteSerialPortData(SerPort,@DataBuffer(5),1)   ;  low byte of the data byte
 
  WriteSerialPortData(SerPort,@SendBuffer(1),1)   ; CR  command
EndProcedure
Procedure transmitStopOff()
  Delay(2)
  DataBuffer(4)=50  ; high data byte = 2
  DataBuffer(5)=54  ;  low data byte = 6
  CANTransmit()
  Delay(2)
EndProcedure
Procedure transmitREM(HighByte.b,LowByte.b)
  DataBuffer(4) = HighByte
  DataBuffer(5) = LowByte
  CANTransmit()
  transmitStopOff()
EndProcedure
Procedure setRemoteLED()
  If Identifier = "02F"
    
    ;colorBIT(0) = StrU(BIT(40),#PB_Byte)
    ;colorBIT(1) = StrU(BIT(41),#PB_Byte)
    ;colorBIT(2) = StrU(BIT(42),#PB_Byte)
    ;colorBIT(3) = StrU(BIT(43),#PB_Byte)
    ;colorBIT(4) = StrU(BIT(44),#PB_Byte)
    ;colorBIT(5) = StrU(BIT(45),#PB_Byte)
    ;colorBIT(6) = StrU(BIT(46),#PB_Byte)
    ;colorBIT(7) = StrU(BIT(47),#PB_Byte)
    
    For m=0 To 7
      colorBIT(m) = StrU(BIT(m+40),#PB_Byte)                    ; initialize array colorBIT() with data byte 5 
    Next
    
    SetGadgetText(#UPString,colorBIT(0))
    If colorBIT(0) = "0"                                        ; Up
      SetGadgetColor(#UPString,#PB_Gadget_BackColor,$080FF7)    ; red
    Else
      SetGadgetColor(#UPString,#PB_Gadget_BackColor,$70D56A)    ; green
    EndIf 
    
    SetGadgetText(#DOWNString,colorBIT(1))
    If colorBIT(1) = "0"                                        ; Down
      SetGadgetColor(#DOWNString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#DOWNString,#PB_Gadget_BackColor,$70D56A)
    EndIf 
    
    SetGadgetText(#OFFString,colorBIT(2))
    If colorBIT(2) = "0"                                        ; Mag Off
      SetGadgetColor(#OFFString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#OFFString,#PB_Gadget_BackColor,$70D56A)
    EndIf 
    
    SetGadgetText(#ONString,colorBIT(3)) 
    If colorBIT(3) = "0"                                        ; Mag On
      SetGadgetColor(#ONString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#ONString,#PB_Gadget_BackColor,$70D56A)
    EndIf  
    
    SetGadgetText(#FORString,colorBIT(4))   
    If colorBIT(4) = "0"                                        ; Forward
      SetGadgetColor(#FORString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#FORString,#PB_Gadget_BackColor,$70D56A)
    EndIf 
    
    SetGadgetText(#STOPString,colorBIT(5))
    If colorBIT(5) = "0"                                        ; Stop
      SetGadgetColor(#STOPString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#STOPString,#PB_Gadget_BackColor,$70D56A)
    EndIf 
    
    SetGadgetText(#BACKString,colorBIT(6))
    If colorBIT(6) = "0"                                        ; Backward
      SetGadgetColor(#BACKString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#BACKString,#PB_Gadget_BackColor,$70D56A)
    EndIf 
    
    SetGadgetText(#EM_STOPString,colorBIT(7))
    If colorBIT(7) = "0"                                        ; Emergency Stop
      SetGadgetColor(#EM_STOPString,#PB_Gadget_BackColor,$080FF7)
    Else
      SetGadgetColor(#EM_STOPString,#PB_Gadget_BackColor,$70D56A)
    EndIf      
  EndIf
EndProcedure
Procedure handleEvents(EventGadget)
  HighByte.b
  LowByte.b
  
  Select EventGadget
    Case #EM_STOPButton
      SetGadgetState(#EM_STOPButton,#True)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 65                       ; => A
      LowByte  = 54                       ; => 6
      transmitREM(HighByte,LowByte)       ; data byte = A6
    Case #BACKButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#True)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 54                       ; => 6
      LowByte  = 54                       ; => 6
      transmitREM(HighByte,LowByte)       ; data byte = 66
    Case #STOPButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#True)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 48                       ; => 0
      LowByte  = 54                       ; => 6
      transmitREM(HighByte,LowByte)       ; data byte = 06
    Case #FORButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#True)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 51                       ; => 3
      LowByte  = 54                       ; => 6
      transmitREM(HighByte,LowByte)       ; data byte = 36
    Case #ONButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#True)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 50                       ; => 2
      LowByte  = 69                       ; => 6
      transmitREM(HighByte,LowByte)       ; data byte = 26
    Case #OFFButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#True)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 50                       ; => 2
      LowByte  = 50                       ; => 2
      transmitREM(HighByte,LowByte)       ; data byte = 22
    Case #UPButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#True)
      SetGadgetState(#DOWNButton,#False)
      HighByte = 50                       ; => 2
      LowByte  = 55                       ; => 7
      transmitREM(HighByte,LowByte)       ; data byte = 27
    Case #DOWNButton
      SetGadgetState(#EM_STOPButton,#False)
      SetGadgetState(#BACKButton,#False)
      SetGadgetState(#STOPButton,#False)
      SetGadgetState(#FORButton,#False)
      SetGadgetState(#ONButton,#False)
      SetGadgetState(#OFFButton,#False)
      SetGadgetState(#UPButton,#False)
      SetGadgetState(#DOWNButton,#True)
      HighByte = 50                       ; => 2
      LowByte  = 52                       ; => 4
      transmitREM(HighByte,LowByte)       ; data byte = 24
  EndSelect
  
EndProcedure

;##################### main #####################

initCAN()
createWindow()

Repeat ; Eventloop
  Event = WindowEvent()
  EventGadget = EventGadget()
  
  Ergebnis = AvailableSerialPortInput(SerPort)
    
  If Ergebnis
    receiveCANMessage()
  EndIf  
  
  If val_flag = 1
    SetGadgetText(#IDString,Identifier)
    SetGadgetText(#D0String,DB(0))
    SetGadgetText(#D1String,DB(1))
    SetGadgetText(#D2String,DB(2))
    SetGadgetText(#D3String,DB(3))
    SetGadgetText(#D4String,DB(4))
    SetGadgetText(#D5String,DB(5))
    SetGadgetText(#D6String,DB(6))
    SetGadgetText(#D7String,DB(7))
    
    setRemoteLED()
    val_flag = 0
  EndIf
  ; hier fängt mein code zu spinnen an, GadgetState bleibt leider immer auf 0 und somit komme ich nie in den ElseIf zweig,
  ; welcher nötig ist um die message mehrmals zu senden
  If Event = #PB_Event_Gadget
    EventGadgetOld = EventGadget
    GadgetState = GetGadgetState(EventGadgetOld)
    handleEvents(EventGadget)
 ElseIf GadgetState
    handleEvents(EventGadgetOld)
  EndIf
  
Until Event = #PB_Event_CloseWindow
closeCAN()
CloseSerialPort(SerPort)
End
Hoffe auf baldige Antworten :)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von Kaeru Gaman »

Hallo und Willkommen an Board! :D

ohne deinen code zu lesen tipp ich mal, dass du mehrfach (Wait)WindowEvent drin hast.

(jetzt poste ich erst mal, dann les' ich deinen code)


PS... sieh mal einer an.. das ist es nicht, sondern tatsächlich einige Level anspruchsvoller... :mrgreen:

SetGadgetText und SetGadgetState erzeugen Events.
du darfst also nicht einfach einen unbedingten Bereich in der Hauptschleife haben, die mehrere Events erzeugt, dann läuft deine Queue über.
ein reines WindowEvent wartet auch überhaupt nicht sondern rauscht durch, das verschärft das Problem noch mal.

Benutze lieber ein WaitWindowEvent(50), damit wird deine Hauptschleife immer bei Events durchlaufen, und wenn keines anliegt nur alle 50ms.
diese geschichten die mehrere Events erzeugen und zeitgesteuert laufen sollen führst du nur aus, wenn Event = #Null

.... soviel erstmal in kürze, aber ich fürchte, des Pudels Kern hab ich noch nicht erreicht damit.

... und wenn ich mir deinen Code so ansehe, brauchst du nicht in "Anfänger" zu posten, auch wenn du neu im Forum bist. ;)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von Kaeru Gaman »

PPS:
also probier erstmal diese Umstrukturierung:

Code: Alles auswählen

    Repeat ; Eventloop
      Event = WaitWindowEvent(50)
      EventGadget = EventGadget()
     
      Ergebnis = AvailableSerialPortInput(SerPort)
       
      If Ergebnis
        receiveCANMessage()
      EndIf 
  
      Select Event
        Case #PB_Event_Gadget
          EventGadgetOld = EventGadget
          GadgetState = GetGadgetState(EventGadgetOld)
          handleEvents(EventGadget)

        Case #Null    ; TimeOut
          handleEvents(EventGadgetOld)
          If val_flag = 1
            SetGadgetText(#IDString,Identifier)
            SetGadgetText(#D0String,DB(0))
            SetGadgetText(#D1String,DB(1))
            SetGadgetText(#D2String,DB(2))
            SetGadgetText(#D3String,DB(3))
            SetGadgetText(#D4String,DB(4))
            SetGadgetText(#D5String,DB(5))
            SetGadgetText(#D6String,DB(6))
            SetGadgetText(#D7String,DB(7))
            setRemoteLED()
            val_flag = 0
          EndIf

        Case #PB_Event_CloseWindow
          EXIT = 1
      EndSelect   
     
    Until EXIT
bräuchte ich ein externes Gerät?

getestet hab ich jetzt garnicht - hab keine Zeit, muss jetzt wech...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
alDo
Beiträge: 41
Registriert: 28.01.2010 16:50
Wohnort: Hannover

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von alDo »

Erst mal Danke für den Tipp mit dem WaitWindowEvent(). Wenn ich meinen Code nach deinen Vorgaben umstrukturiere und teste, funktionieren die Buttons einwandfrei (kein Delay). Allerdings wird die Message nur bei jedem Klick auf den Button gesendet(wie bei normalen Butons eben) :( Nachdem ich in der Hilfe den Abschnitt Windows Message Handling durchgelesen habe, kam ich auf diese Idee hier:

Code: Alles auswählen

Repeat ; Eventloop
  Event = WaitWindowEvent(50)
  EventGadget = EventGadget()
  
  Ergebnis = AvailableSerialPortInput(SerPort)
    
  If Ergebnis
    receiveCANMessage()
  EndIf  
  
  If val_flag = 1
    SetGadgetText(#IDString,Identifier)
    SetGadgetText(#D0String,DB(0))
    SetGadgetText(#D1String,DB(1))
    SetGadgetText(#D2String,DB(2))
    SetGadgetText(#D3String,DB(3))
    SetGadgetText(#D4String,DB(4))
    SetGadgetText(#D5String,DB(5))
    SetGadgetText(#D6String,DB(6))
    SetGadgetText(#D7String,DB(7))
    setRemoteLED()
    val_flag = 0
  EndIf
  
  While WindowEvent() : Wend             ; hier der Abschnitt aus der Hilfe
  
  Select Event
  
    Case #PB_Event_Gadget
      EventGadgetOld = EventGadget
      GadgetState = GetGadgetState(EventGadgetOld)
      handleEvents(EventGadget)
      
    Case #Null                      ; Timeout
      If GadgetState                              ; Hier noch die Abfrage nach dem aktuellem Status des alten Gadgets
        handleEvents(EventGadgetOld)
      EndIf
      
    Case #PB_Event_CloseWindow
       EXIT = 1
  EndSelect
Until EXIT
Mit dieser Implementierung funktioniert mein Programm genau so wie ich mir das vorgestellt habe. Nur habe ich jetzt nicht die Möglichkeit das Programm auf normalen Wege zu schliessen. Sprich ich muss jedes mal in den Task Manager und die Anwendung beenden. Wäre ja zu schön gewesen...

Zum Testen bräuchtest du schon externe Geräte. Ich benutz u.a. ein Programm welches automatisch Messages über den ComPort senden und empfangen kann.
OS: Windows XP
PB: 4.40 (x86)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von Kaeru Gaman »

also, die reaktion auf val_flag würde ich schon im timeout lassen.
oder ggf. statt val_flag = 1 direkt einen procedure-call wo du die anzeige durchführst.

warum sich das programm jetzt nicht mehr beenden läßt ist mir allerdings schleierhaft.


welche routine ist denn die, die das senden durchführt?
gehe ich recht in der annahme, dass der erneute Aufruf von handleEvents das tut?

du könntest auch anstatt über EventGadgetOld zu gehen,
die Status aller gewünschten toggle-buttons abfragen und darauf reagieren.

Code: Alles auswählen

        Case #Null
          If GetGadgetState(#ONButton)
            handleEvents(#ONButton)
          EndIf
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
alDo
Beiträge: 41
Registriert: 28.01.2010 16:50
Wohnort: Hannover

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von alDo »

Wenn du mit reaktion auf val_flag den if-Block meinst, das habe ich schon versucht. Dann funktionieren die Buttons wie gewöhnliche und nicht wie Toggle-Buttons.
Also meinst du, ich sollte den Abschnitt mit SetGadgetText in ein Prozedur schreiben?

So etwa?

Code: Alles auswählen

If val_flag = 1
  setMessage()
  setRemoteLED()
  val_flag = 0
EndIf
Was ändert das? Was denkst du von der Zeile, die ich aus der Hilfe habe? Wenn ich diese auskommentiere kann ich mein Programm auch wieder schliessen. Wenn du mit routine eine meiner Prozeduren meinst dann dürfte das transmitREM() sein. Diese wird wie du richtig vermutet hast in handleEvents() aufgerufen. (siehe dazu letzte deklarierte Prozedur in meinem ersten Post).
Ich versuchs mal mit deinem Tipp die Buttons einzeln abzufragen.
OS: Windows XP
PB: 4.40 (x86)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von Kaeru Gaman »

nein, ich meine, dort wo du val_flag auf 1 setzt, dort könntest du auch eine procedure aufrufen.

Code: Alles auswählen

Procedure Val_Flag()
            SetGadgetText(#IDString,Identifier)
            SetGadgetText(#D0String,DB(0))
            SetGadgetText(#D1String,DB(1))
            SetGadgetText(#D2String,DB(2))
            SetGadgetText(#D3String,DB(3))
            SetGadgetText(#D4String,DB(4))
            SetGadgetText(#D5String,DB(5))
            SetGadgetText(#D6String,DB(6))
            SetGadgetText(#D7String,DB(7))
            setRemoteLED()
EndProcedure
und die Anweisung

Code: Alles auswählen

val_flag = 1
ersetzt du durch den Call

Code: Alles auswählen

Val_Flag()

... leider ist das etwas schwierig, so "remote"
ohne selbst testen zu können ist es ein bißchen wie blind rückenschwimmen...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
alDo
Beiträge: 41
Registriert: 28.01.2010 16:50
Wohnort: Hannover

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von alDo »

Yo, ich bins wieder.
... leider ist das etwas schwierig, so "remote"
ohne selbst testen zu können ist es ein bißchen wie blind rückenschwimmen...
Hast wohl heimlich mit Augenbinde im Schwimmbad geübt^^

Jedenfalls habe ich deinen Rat beherzigt und mehrere If-Anweisungen eingebaut. Der Code läuft jetzt perfekt. Ich kann sogar das Fenster schliessen <)

Der Vollständigkeit halber noch das funktionierende Main-Programm:

Code: Alles auswählen

;##################### main #####################

initCAN()
createWindow()
Repeat                                          ; Eventloop
  Event = WaitWindowEvent(50)                    ; sending period
  EventGadget = EventGadget()
  
  Ergebnis = AvailableSerialPortInput(SerPort)
    
  If Ergebnis
    receiveCANMessage()
  EndIf  
    
  Select Event
  
    Case #PB_Event_Gadget
      
      If GetGadgetState(EventGadget)            ; second click on toggled button stops transmit
        handleEvents(EventGadget)
      EndIf
      
      
    Case #Null                                  ; Timeout (transmit data of toggled button)
      
      If GetGadgetState(#EM_STOPButton)
        handleEvents(#EM_STOPButton)
      EndIf
      
      If GetGadgetState(#BACKButton)
        handleEvents(#BACKButton)
      EndIf
            
      If GetGadgetState(#STOPButton)
        handleEvents(#STOPButton)
      EndIf
            
      If GetGadgetState(#FORButton)
        handleEvents(#FORButton)
      EndIf
            
      If GetGadgetState(#ONButton)
        handleEvents(#ONButton)
      EndIf
            
      If GetGadgetState(#OFFButton)
        handleEvents(#OFFButton)
      EndIf
            
      If GetGadgetState(#UPButton)
        handleEvents(#UPButton)
      EndIf
            
      If GetGadgetState(#DOWNButton)
        handleEvents(#DOWNButton)
      EndIf
      
    Case #PB_Event_CloseWindow
       EXIT = 1
       
  EndSelect
  
Until EXIT
closeCAN()
CloseSerialPort(SerPort)
End
Noch mal vielen Dank für die Hilfe Kaeru :allright:

Da das Programm jetzt läuft, habe ich jetzt noch Fragen bezüglich meiner Programmstruktur allgemein. Z.B. wie vermeide ich möglichst den Gebrauch von den globalen Variablen(siehe erster Post). Da ich mir sehr gut vorstellen kann in näherer Zukunft mit diesen Prozeduren wieder zu arbeiten, stellt sich mir jetzt natürlich die Frage wie ich die einzelnen Prozeduren auslagere (deswegen wenig globale Variablen) und organisiere. Spontan würde mir da beispielsweise eine Datei einfallen in der ich alle meine Konstanten speichere usw.

Hoffe Du kannst mir da als erfahrener PB User ein paar Tipps geben :mrgreen:
OS: Windows XP
PB: 4.40 (x86)
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Brauche Hilfe u.a. bei Umgang mit Toggle-Buttons

Beitrag von Kaeru Gaman »

die konstanten brauchst du nicht auslagern.
die kannst du in jedem Include, wo sie benötigt werden, gleich definieren.
(nur der Versuch mit einem anderen Wert nochmal zu definieren erzeugt einen Fehler)
oder du benutzt ein einziges Include wo du alle deine Konstanten definierst.

falls das noch Teil deiner Frage war: XIncludeFile ermöglicht dir, Code-Abschnitte die du wiederverwendest auszulagern.


Globale Variablen zu vermeiden ist natürlich gut, manches läßt sich aber mit einer Globalen eben doch einfacher lösen als irgendwelche Klimmzüge zu veranstalten.

wenn du bestimmte Variablen in einem Kreis von Funktionen gemeinsam verwendest, kannst du sie auch Shared definieren.
das ist vielleicht bei deinen DB() Arrays angebracht. außerdem kann man sie und die Funktionen noch mit einem präfix benennen, um klar zu machen, zu welcher Bibliothek sie gehören.
hier würde sich vielleicht anbieten, allen den Präfix CAN zu geben:

Code: Alles auswählen

    Shared Dim CAN_DB.s(7)
    Shared Dim CAN_DBH.s(7)
    Shared Dim CAN_DBL.s(7)
    Procedure CAN_initCAN()
    Procedure CAN_openCAN()
    Procedure CAN_closeCAN()
    Procedure CAN_readSerPort()
    Procedure CAN_receiveCANMessage()
    Procedure CAN_Transmit()
    Procedure CAN_transmitStopOff()
um wiederum Lokale Variablen sicher abzukapseln verwende Protected.

die meisten Werte können als Argumente oder Rückgabewerte übergeben werden, da braucht man garnichts Gemeinsames.
ist dann natürlich auch eine Frage der Prozeduren-Struktur, dass man mit nur einem Rückgabewert auskommt.

man kann aber auch an die Procedure einen Zeiger zu einer Struktur übergeben, die die Procedure dann füllen soll,
dann verwendet man üblicher Weise den Rückgabewert zur Fehlermeldung. das ist auch die übliche Konvention für einen API-Call.

Schleifenvariablen sollten natürlich immer Local und Protected sein, egal ob man sie jetzt n, i oder counter nennt.


und ansonsten... lies halt einfach im Forum was dich interessiert, du wirst ne Menge aufschnappen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten