Infrarot Empfänger (WinLIRC) mit PB???

Hardware- und Elektronikbasteleien, Ansteuerung von Schnittstellen und Peripherie.
Fragen zu "Consumer"-Problemen kommen in Offtopic.
Nik
Beiträge: 132
Registriert: 04.02.2005 19:57

Beitrag von Nik »

Wie ist das jetzt bei dem eingebauten IrDA Port eines Laptops (Auf dem läuft Linux)?
mfg Nik
www.KoMaNi.de
Eine kleine Gruppe von Hobby Programmierern, die gerade einen Instant Messenger natürlich in PureBasic schreiben.
Benutzeravatar
Helmut
Beiträge: 162
Registriert: 20.09.2004 22:53

Beitrag von Helmut »

@osta
Hänge doch bitte deinen Code "ran".
osta
Beiträge: 87
Registriert: 08.09.2004 11:48
Wohnort: Morsbach (Am Arsch der Welt)
Kontaktdaten:

Code

Beitrag von osta »

Hier ist das komplette Programm, was ich benutze um meinen PC zu steuern. Es bentutzt eine Konfigurationsdatei "remote.ctr" zu der ich gleich noch was sage:

Code: Alles auswählen

Structure code
  code.s
  name.s
EndStructure
Global HCom, time
#ESC = 27
#Return = 13
#Space = 32
#Right = 39
#Left = 37
#up = 38
#down = 40
#TAB = 9
Procedure ExitWindowsX(shutdown.l, flags.l, force.l)
  Privileges.TOKEN_PRIVILEGES 
  OpenProcessToken_(GetCurrentProcess_(), 40, @hToken) 
  Privileges\PrivilegeCount           = 1 
  Privileges\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED 
  LookupPrivilegeValue_(0, "SeShutdownPrivilege", @Privileges\Privileges[0]\Luid) 
  AdjustTokenPrivileges_(hToken, 0, @Privileges, 0, 0, 0) 
  CloseHandle_(hToken)
  If shutdown
    If force
      ExitWindowsEx_(flags|#EWX_FORCE, 0)
    Else
      ExitWindowsEx_(flags, 0)
    EndIf
  Else
    SetSystemPowerState_(flags, force)
  EndIf
EndProcedure
Procedure.s GetComBytes()
  Car.b = 0
  Chaine.s = ""
  While ComInputBufferCount(HCom) > 0
    If ComReadByte(HCom,@Car, 1) <> 0
      If Car <> 0
        Chaine = Chaine + Str(Car)+"."
      EndIf
    Else
      Break
    EndIf
  Wend
  ProcedureReturn Chaine
EndProcedure
Procedure SDTimer()
  OpenWindow(1, 0, 0, 300, 200, #PB_Window_ScreenCentered|#PB_Window_TitleBar, "Shutdown-Timer")
  CreateGadgetList(WindowID())
  TextGadget(10, 5, 5, 300, 190, "XX:XX")
  SetGadgetFont(10, LoadFont(1, "Comic Sans MS", 72))
  Repeat
    WindowEvent()
    If time >= 3600 Or time =0
      time=0
      CloseWindow(1)
      ProcedureReturn    
    Else
        time-1
    EndIf
    Delay(1000)
    SetGadgetText(10, Str(time/60)+":"+Str(time-(time/60)*60))
  Until time <= 5 And time > 0
  ExitWindowsX(0,0,1)
EndProcedure
Procedure InitRemoteControl()
NewList code.code()
If OpenFile(0,"remote.ctr") = 0:MessageRequester("Fehler", "Konnte remote.ctr nicht öffnen", 16):End:EndIf
Repeat
  s.s = ReadString()
  If s = ""
    Break
  Else
    AddElement(code())
    code()\name = StringField(s, 1, "=")
    code()\code = StringField(s, 2, "=")
    Debug code()\name+" - "+code()\code
  EndIf
ForEver
CloseFile(0)
Debug "found " + Str(CountList(code()))+" codes"
Port.s = "com1:1200,n,8,1"
Handshake.l = 1
Buffer.l = 1024
Car.s = ""
Chaine.s
HCom.l = ComOpen(Port, Handshake,Buffer,Buffer)
ProcedureReturn HCom
EndProcedure
Procedure.s GetRemoteButton()
  Protected string.s
  If ComInputBufferCount(HCom) <7
    ProcedureReturn ""
  EndIf
  Repeat
    string + GetComBytes()
  Until ComInputBufferCount(HCom) = 0
  If Len(string)<20
    ProcedureReturn ""
  EndIf
  ForEach code()
      If FindString(string, code()\code, 1)
        Debug code()\name
        ProcedureReturn code()\name
      EndIf
  Next
  Debug string
EndProcedure
If InitRemoteControl() = 0:MessageRequester("Fehler", "Konnte nicht...", 16):End:EndIf
InitCDAudio()
hWnd1 = OpenWindow(2,0,0,1024,768,#PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible,"")
MakeStayOnTop(hWnd1,1)
hBrush1 = CreateSolidBrush_(RGB(0, 0, 0)) 
SetClassLong_(hWnd1, #GCL_HBRBACKGROUND, hBrush1) 
InvalidateRect_(hWnd1, #Null, #True)
AddSysTrayIcon(0, hWnd1, CatchImage(0, ?symbol))
CreatePopupMenu(0)
MenuItem(1, "Found "+Str(CountList(code()))+" Buttons")
MenuItem(0, "Beenden")
Repeat
  button.s = GetRemoteButton()
  If RTrim(button) <> ""
    Select button; Immer aktive Funktionen
      Case "1"
        UseCDAudio(0)
        If cdej1
          EjectCDAudio(0)
          cdej1 = 0
        Else
          EjectCDAudio(1)
          cdej1 = 1
        EndIf
      Case "2"
        UseCDAudio(1)
        If cdej2
          EjectCDAudio(0)
          cdej2 = 0
        Else
          EjectCDAudio(1)
          cdej2 = 1
        EndIf
      Case "mute"
        If mute = 0
          mute = 1
        Else
          mute = 0
        EndIf
        SetMute(0, #Mixer_Type_Speaker, mute)
    Case "memo"
      If black
        HideWindow(2,1)
        black=0
      Else
        HideWindow(2,0)
        SetCursorPos_(1030, 200)
        black=1
      EndIf
    Case "cont+"
      If time = 0
        time = 10*60
        CreateThread(@SDTimer(), 0)
      Else
        time + 600
      EndIf
    Case "cont-"
      time - 600
      If time < 0
        time = 0
      EndIf
    Case "vol+"
      vol = GetVolume1000(0, #Mixer_Type_Speaker)+50
      If vol > 1000
        vol = 1000
      EndIf
      SetVolume1000(0, #Mixer_Type_Speaker, vol)
    Case "vol-"
      vol = GetVolume1000(0, #Mixer_Type_Speaker)-50
      If vol < 0
        vol = 0
      EndIf
      SetVolume1000(0, #Mixer_Type_Speaker, vol)
  EndSelect   
  If FindWindow_(@"WindowClass_0", @"SUSI")
    If button = "3"
      susi = 1
      ShowWindow_(FindWindow_(@"WindowClass_0", @"SUSI"), 1)
      Debug "set susi = 1"
    EndIf
    If susi = 1
      Select button; SUSI
        Case "||"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 0, 0)
        Case ">"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 1, 0)
        Case "3>"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 5, 0)
        Case "pfeil"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 3, 0)
        Case ">|"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 2, 0)
        Case "|<"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 7, 0)
        Case "a"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 8, 0)
        Case "b"
          PostMessage_(FindWindow_(@"WindowClass_0", @"SUSI"), #wm_keydown, 57, 0)
      EndSelect
      If button <> "3" And button <> ""
        susi = 0
        Debug "set susi = 0"
        ShowWindow_(FindWindow_(@"WindowClass_0", @"SUSI"), 0)
        Continue
      EndIf
    EndIf
  EndIf
  If FindWindow_(@"Class of CyberLink Universal Player", 0) And susi = 0
    Select button; PowerDVD
      Case "c"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("H"), 0) 
      Case "a"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("U"), 0) 
      Case ">>"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, #TAB, 0) 
      Case "pr<>"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("O"), 0) 
      Case "pfeil"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("Z"), 0) 
        SetCursorPos_(1030, 0)
      Case "stop"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("S"), 0) 
      Case "|<"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("P"), 0)
      Case ">|"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, Asc("N"), 0)
      Case ">"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, #Return, 0)
      Case "||"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_keydown, #Space, 0)
      Case "power"
        PostMessage_(FindWindow_(@"Class of CyberLink Universal Player", 0), #wm_close, 0, 0)
    EndSelect
  ElseIf FindWindow_(@"Winamp v1.x", 0) And susi = 0
    hwnd_Winamp_ = FindWindow_(@"Winamp PE", 0)
    Select button; Winamp Funktionen
      ;Case "pfeil"
      ;Winamp_ExecuteVis(); Braucht den Winamp Include...kann hier aber weggelassen werden
    Case "<<"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, #Left, 0)
    Case ">>"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, #Right, 0)
    Case "a"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("S"), 0)
    Case "b"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("R"), 0)
    Case "power"
      PostMessage_(FindWindow_(@"Winamp v1.x", 0), #wm_close, 0, 0)
    Case ">"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("X"), 0)
    Case "||"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("C"), 0)
    Case "stop"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("V"), 0)
    Case ">|"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("B"), 0)
    Case "|<"
      PostMessage_(FindWindow_(@"Winamp PE", 0), #wm_keydown, Asc("Z"), 0)
  EndSelect
ElseIf FindWindow_(@"Media Player 2", 0) And susi = 0
  hwnd = FindWindow_(@"Media Player 2", 0)
  Select button; Winamp Funktionen
    Case "||"
      PostMessage_(hwnd, #wm_keydown, Asc(" "), 0)
    Case "stop"
      PostMessage_(hwnd, #wm_keydown, Asc("."), 0)
  EndSelect
Else
  Select button; Funktionen wenn Winamp und so NICHT da sind
    Case "stop"
     PostMessage_(GetForegroundWindow_(), #wm_keydown, #Return, 0)
    Case "prog+"
      PostMessage_(GetForegroundWindow_(), #wm_keydown, #up, 0)
    Case "prog-"
      PostMessage_(GetForegroundWindow_(), #wm_keydown, #down, 0)
    Case ">>"
      PostMessage_(GetForegroundWindow_(), #wm_keydown, #Right, 0)
    Case "<<"
      PostMessage_(GetForegroundWindow_(), #wm_keydown, #Left, 0)
    Case "b"
      For k = 0 To 10
        Delay(100)
        WindowEvent()
        Select GetRemoteButton()
          Case "1"
            par.s = "cd.pls"
            Break
          Case "2"
            par.s = "Videos.pls"
            Break
          Case "3"
            par.s = "musik.pls"
          Case "pr<>"
            par.s = "xxx.pls"
            Break
        EndSelect
      Next
      RunProgram("C:\Programme\Musik-Video\PowerDVD\PowerDVD.exe",par,"C:\Programme\Musik-Video\PowerDVD\")
    Case "a"
      For k = 0 To 10
        Delay(100)
        WindowEvent()
        Select GetRemoteButton()
          Case "1"
            par.s = "mp3musik.m3u"
            Break
          Case "2"
            par.s = "ddf.m3u"
            Break
          Case "3"
            par.s = "christl.m3u"
        EndSelect
      Next
        RunProgram("C:\Programme\Musik-Video\Winamp\winamp.exe", par, "C:\Dokumente und Einstellungen\Administrator.THOMMY\Eigene Dateien")
    Case "power"
    OpenWindow(0, 0, 0, 300, 80, #PB_Window_BorderLess|#PB_Window_ScreenCentered, "")
    CreateGadgetList(WindowID())
    TextGadget(0, 10, 35, 200, 50, "Windows beenden?")
    For k = 0 To 10
      Delay(100)
      WindowEvent()
      Select GetRemoteButton()
        Case "power"
         ExitWindowsX(0,0,1)
        Case "mute"
          ExitWindowsX(0, 1, 1)
        Case "memo"
          ExitWindowsX(1,0,1)
       EndSelect
    Next
    CloseWindow(0)
  EndSelect
EndIf
EndIf
Delay(100)
event = WindowEvent()
If event = #PB_Event_SysTray
  Select EventType()
    Case #PB_EventType_LeftClick
      DisplayPopupMenu(0, hWnd1)
  EndSelect
ElseIf event = #PB_Event_Menu
  Select EventMenuID()
    Case 0
      End
  EndSelect
EndIf
ForEver
DataSection
symbol:
IncludeBinary "EYE.ico"
EndDataSection 
Ein Symbol müsst ihr allerdings noch besorgen, da das Programm nur für den Tray bestimmt ist.
Um eine Fernbedienung zu konfigurieren, einfach im DEBUG-Modus starten und eine Taste (Fernbedienung) mehrmals drücken. Der Debugger zeigt die empfangenen Daten an, die (großtenteils) identisch sind. Der Teil, der am besten erkannt wird (am besten mind. 4 bytes) wird dann in die "remote.ctr" eingetragen, die so aussehen muss:

Code: Alles auswählen

memo=16.38.-111.-52.-103.36.9
mute=16.38.-111.76.100.-119.34
power=16.38.-111.76.66.100.68
1=16.38.-111.76.38.36.-103
2=16.38.-111.-52.25.68.34
3=16.38.-111.76.102.38.-103
4=16.38.-111.-52.38.34.-103
Also immer ButtonName$=Byte1.Byte2.Byte3...
Je weniger Bytes, desto größer die Erkennung, aber falls mehrere Codes die gleichen Bytes enthalten (in der gleichen Reihenfolge) sollte man das nächste Byte dazunehmen ;)

MfG
Ich hänge zu oft und zu lange vor dem PC! Ich muss dringend was an meinem Lebenswandel verändern!.......
Nur heute geht's grad nicht.
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Hast du also heraus gefunden an welchen Pin dein Empfänger die Daten sendet ?

Code: Alles auswählen

While ComInputBufferCount(HCom) > 0 
    If ComReadByte(HCom,@Car, 1) <> 0 
Also doch an RX und nicht an /*Edit*/DCD ?
Zuletzt geändert von MARTIN am 28.11.2005 21:29, insgesamt 1-mal geändert.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
osta
Beiträge: 87
Registriert: 08.09.2004 11:48
Wohnort: Morsbach (Am Arsch der Welt)
Kontaktdaten:

Beitrag von osta »

nee. Keine Ahnung. Aber ich denke auf keinen Fall an RI.
Also die Daten kommen genau so an, wie AT Befehle beim Modem. Nur halt nicht als String, sondern als Bytes (was ja im Prinzip das selbe ist).
Wie das Ding aufgebaut ist, keine Ahnung, aber ich denke, wenn da steht LIRC kompatibel, werden die alle gleich funktionieren.
Ich glaub die COM-Port Funktionen hab ich aus ner LIB, aber es gibt ähnliche Befehle in der API (Hab schon mehrere Forum-Threads gesehen. Thema: "Daten an serielle Schnittstelle senden und empfangen")
Ich hänge zu oft und zu lange vor dem PC! Ich muss dringend was an meinem Lebenswandel verändern!.......
Nur heute geht's grad nicht.
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Schuldigung, ich meinte DCD nicht RI.
wenn da steht LIRC kompatibel, werden die alle gleich funktionieren
Naja auf der LIRC-Seite angefürten Beispielempfänger, senden die Daten DCD an den Rechner. In deinem Program empfängst du die daten über RX. Sie könnten an RX auch dann gelangen wenn der empfänger zwar an DCD angeschlossen ist aber RX-Pin "in der Luft" hängt. Egal.

Jedenfalls freut mich das es dir gelungen ist den IR-Emfänger nützen zu können.
Ich glaub die COM-Port Funktionen hab ich aus ner LIB, aber es gibt ähnliche Befehle in der API
Die aus der MVCOM-Lib sind doch besser weil portabel.
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Antworten