tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
6
ZUGRIFFE
801
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Blue_Fox Blue_Fox ist offline Mitglied Bronze
    Registriert seit
    Aug 2011
    Beiträge
    32
    Hi Leute

    ich hoff hier bin ich richtig...

    Ich habe folgendes Problem:
    Ich steuere mit einem Touchpanel über den Comport einen uC an. Dies funktioniert auch schon recht gut, nur sollte jetzt der uC auch noch jederzeit etwas an das Touchpanel schicken können! Aber ich kann den ComPort nur ein mal öffnen...

    Meine Idee war jetzt, einen Thread aufzumachen, der ständig auf empfangen ist. Wenn ich was an den uC senden will, setzt ich den Thread in den Sleepmodus, öffne den Comport neu, sende, schließe den Comport wieder und lasse den Thread weiterlaufen.

    Ich weiß nicht mal ob das so funktionieren würde. Das größte Problem ist aber, dass ich aus meinem "Zuhör"Thread an mein normal laufendes Programm eine Meldung und neue variablen übergeben müsste, wenn der uC was geschickt hat.

    Beim CF3.5 funktioniert leider kein Interrupt und mit einer exception "vernichte" ich meinen "Zuhör"Thread...

    Am besten waere ein Event, mit dem ich eine Parameterliste zurueckgeben koennte....

    Wie könnte ich jetzt da eine Kommunikation aufbaun?

    mfg
    Blue Fox
    Geändert von Blue_Fox (09.12.11 um 08:12 Uhr) Grund: Noch was eingefallen...
     

  2. #2
    Avatar von Shakie
    Shakie Shakie ist offline Mitglied Diamant
    Registriert seit
    May 2004
    Ort
    Europa
    Beiträge
    2.048
    Ich glaube, hier liegen zweierlei Probleme vor: einmal die Kommunikation zwischen Threads und einmal die Kommunikation mit der seriellen Schnittstelle.
    Ich vermute, du verwendest die SerialPort-Klasse? Von dieser brauchst du für deinen ganzen Programmablauf nur eine einzige Instanz und der ComPort muss auch nur ein einziges mal geöffnet werden.
    Denn du kannst die Instanz sowohl zum Empfangen als auch zum Senden verwenden. Zum Lesen gibt es mehrere Methoden, deren Namen alle mit "Read..." anfangen (siehe MSDN). Zum Schreiben gibt es analog die Write- und WriteLine-Methoden.
    Außerdem gibt es das DataReceived-Event, das dir mitteilt, wann Daten gesendet wurden. Sobald das Event eintritt solltest du eine der Read-Methoden ausführen.
    Diese Kommunikation erledigst du in einem Thread.
    Den UI-Thread musst du dann nochmal benachrichtigen, dass etwas passiert ist, zum Beispiel mittels Invoke.
     
    hihi = -h²

  3. #3
    Blue_Fox Blue_Fox ist offline Mitglied Bronze
    Registriert seit
    Aug 2011
    Beiträge
    32
    Hi Shakie

    Das mit dem ComPort oeffnen is ne gute Nachricht!! Habs auch gleich umgesetzt...

    Das DataReceived-Event ist fuer meine Zwecke perfekt!! DANKE!!

    So aber jetzt kommt ein weiteres Problem...

    Ich wollte jetzt die kommuniktaion rein auf Events basieren lassen. Wenn ich was empfange habe, is ja auch ganz sinnvoll, da es ja sein kann, dass das Hauptprogramm gar nicht darauf gefasst ist. Nur das senden ueber ein Event funktioniert nicht...

    Da finde ich die Invoke-Methode recht interessant. Nur kapiers ich noch nicht ganz!! erschwerend kommt da hinzu, dass ich fuer WinCE programmiere!!

    Kannst mir da ne bitte ne kleine Starthilfe geben? und kann ich mit der Invoke-Methode einen Rueckgabewert bekommen?

    mfg

    Blue Fox
     

  4. #4
    Avatar von Shakie
    Shakie Shakie ist offline Mitglied Diamant
    Registriert seit
    May 2004
    Ort
    Europa
    Beiträge
    2.048
    Zitat Zitat von Blue_Fox Beitrag anzeigen
    Nur das senden ueber ein Event funktioniert nicht...
    Definier mal bitte, was du damit meinst. "Senden über Event" ergibt für mich keinen Sinn. Oder meinst du Button-Click-Events?
    Von der Invoke-Methode kannst du keinen Rückgabewert erhalten, schließlich wechselst du damit den Thread! (ausser du verwendest BeginInvoke+EndInvoke)
    Invoke sollte auch mit dem Compact Framework funktionieren.
    Starthilfen gibt es auch genügend im Netz. Such einfach mal nach "C# multithreading tutorial"!
     
    hihi = -h²

  5. #5
    Blue_Fox Blue_Fox ist offline Mitglied Bronze
    Registriert seit
    Aug 2011
    Beiträge
    32
    Zitat Zitat von Shakie Beitrag anzeigen
    Definier mal bitte, was du damit meinst. "Senden über Event" ergibt für mich keinen Sinn. Oder meinst du Button-Click-Events?
    !
    Sorry f[r mich klingt das immer so logisch, ich arbeite ja damit....

    Also Ich hab hab mir 2 Events zusammengestellt. Eines wir ausgeloest, wenn ich etwas von der Seriellen Schnittstelle bekomme und mein Hauptprogramm davon was mitbekommen sollte. Hier uebergebe ich auch daten mit einem selbst erstellten Event Arg.

    Jetzt wollte ich das gleiche auch als Befehl zum Senden ueber die serielle Schnittstelle verwenden. In der Theorie funktionierts, nur kann ich dieses Event nicht deklarieren, da ich mir eine endlosschleife baue, wenn ich meinen Thread mit "SerialThread serialTh = new SerialThread();" bekannt mache, da ich ja vom anderen Event schon meine andere Klasse eingebunden habe...

    Beispiel:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    
     
     class SERIAL2
        {
            SERIALThread serialthread = new SERIALThread();
            UDPServer udpserver = new UDPServer();
            
            List<GatewayList> Comlist = new List<GatewayList>();
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Event for sending commands ------------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
     
            public byte[] serialSend(byte[] HAddress, byte RGBRed, byte RGBGreen, byte RGBBlue)
            {
                byte[] message = new byte[8];
     
                HAddress.CopyTo(message, 1);
                message[5] = RGBRed;
                message[6] = RGBGreen;
                message[7] = RGBBlue;
                message[0] = 0x87;
     
                OnSerialwriteEvent(new SerialEventArgs(message));
     
                WaitforAnswer = true;
     
                while (WaitforAnswer) ;
     
                return Returnmessage;
            }
     
            public event EventHandler<SerialEventArgs> SerialwriteEvent;
     
            protected virtual void OnSerialwriteEvent(SerialEventArgs e)
            {
                EventHandler<SerialEventArgs> serialwriteevent = SerialwriteEvent;
                if (serialwriteevent != null)
                {
                    serialwriteevent(this, e);
                }
            }
     
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Event for sending commands end --------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Event for receiving light state changed -----------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
     
            private void Serialrec_SerialrecEvent(object objSender, SerialEventArgs e)
            {
                switch (e.SerialData[0])
                {
                    case 0xAC :
                        verifyMessage(e.SerialData);
     
                        WaitforAnswer = false;
     
                        break;
     
                    case 0xFE :
     
                        HWAddresse[0] = e.SerialData[1];
                        HWAddresse[1] = e.SerialData[2];
                        HWAddresse[2] = e.SerialData[3];
                        HWAddresse[3] = e.SerialData[4];
     
                        for (int i = 0; i < Comlist.Count; i++)
                        {
                            if (HWAddresse == Comlist[i].GetHardwareaddress())
                            {
                                udpserver.UDP_Server_Light(Comlist[i].GetGroup(), Comlist[i].GetAddress());
                                break;
                            }
                        }
                        break;
     
                    case 0xBD :
                        // ToDo: Gateway ready
                        break;
     
                    default :
                        // ToDo: Error
                        break;
                }
            }
     
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Event for receiving light state changed end--------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    
     
     class SERIALThread
        {
            TIMEOUT TimeoutObject = new TIMEOUT();
            SERIAL2 serialcom2 = new SERIAL2();
     
            private Thread timeout;
            private SerialPort ComPort;
     
            byte[] data = new byte[7];
     
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Read message --------------------------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
     
            private void SerialRead(byte cmd, byte[] data)
            {
                byte[] message = new byte[8];
     
                message[0] = cmd;
                data.CopyTo(message, 1);
     
                OnSerialreceiveEvent(new SerialEventArgs(message));
            }
     
            private void DataReceviedHandler(object sender, SerialDataReceivedEventArgs e)
            {
                byte incomingMessage = 0x00;                // only 0x87: 0x01 / 0x87 + 0xFE: 0x02 / 0x87 + 0xAC: 0x04 / 0x87 + 0xBD: 0x08
                ushort receiveddata = 0x00;
     
                SerialPort sp = (SerialPort)sender;
     
                // Timeout
                timeout = new Thread(TimeoutThread);
                timeout.IsBackground = true;
                TimeoutObject.TimeOutEvent += TimeOut_TimeOutEvent;
     
                switch (incomingMessage)
                {
                    case 0x00:
                        if (Encoding.ASCII.GetByteCount(sp.ReadExisting()) == 0x87)
                        {
                            timeout.Start();
                            incomingMessage = 0x01;
                        }
                        else
                        {
                            // ToDo Error
                        }
                        break;
     
                    case 0x01:
                        switch (Encoding.ASCII.GetByteCount(sp.ReadExisting()))
                        {
                            case 0xFE :                  // light changed manually
                                incomingMessage = 0x02;
                                break;
     
                            case 0xAC :                  // normal light changed 
                                incomingMessage = 0x04;
                                break;
                            
                            case 0xBD :                  // gateway ready
                                incomingMessage = 0x08;
                                break;
                        }
                        break;
     
                    case 0x02:
                        receiveddata++;
                        data = Encoding.ASCII.GetBytes(sp.ReadExisting());
     
                        if (receiveddata == 6)
                        {
                            timeout.Abort();
                            receiveddata = 0x00;
                            SerialRead(0x02, data);
                        }
                        break;
     
                    case 0x04 :
                        receiveddata++;
                        data = Encoding.ASCII.GetBytes(sp.ReadExisting());
     
                        if (receiveddata == 3)
                        {
                            timeout.Abort();
                            receiveddata = 0x00;
                            SerialRead(0x04, data);
                        }
                        break;
     
                    case 0x08 :
                        receiveddata++;
                        data = Encoding.ASCII.GetBytes(sp.ReadExisting());
     
                        SerialRead(0x08,data);
                        break;
     
                    default:
                        break;
                }
            }
     
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Read message end ----------------------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Send message -------------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/
     
            private void Serialwrite_SerialwriteEvent(object objSender, SerialEventArgs e)
            {
               ComPort.Write(e.SerialData, 0, e.SerialData.Length);
            }
     
    /*----------------------------------------------------------------------------------------------------------------------------*/
    /*------ Send message end ---------------------------------------------------------------------------------*/
    /*----------------------------------------------------------------------------------------------------------------------------*/

    Ich werde jetzt mal versuchen, den Sendebefehl mit einem Invoke zu versuchen....

    mfg
    Blue Fox
     

  6. #6
    Avatar von Shakie
    Shakie Shakie ist offline Mitglied Diamant
    Registriert seit
    May 2004
    Ort
    Europa
    Beiträge
    2.048
    Es macht ein bisschen den Eindruck auf mich als wäre dir nicht ganz klar, was ein Event ist. Ein Event ist, 1-zu-1 übersetzt, ein Ereignis. Das heißt es muss etwas passieren, und dann wird darauf reagiert.
    Im Beispiel des DataReceived-Events passiert also, dass Daten empfangen werden und reagiert wird mit dem Aufruf deiner DataReceviedHandler-Funktion.
    Was soll bei dir das Ereignis sein, das das Senden von Daten auslösen soll?
     
    hihi = -h²

  7. #7
    Blue_Fox Blue_Fox ist offline Mitglied Bronze
    Registriert seit
    Aug 2011
    Beiträge
    32
    Hi Shakie

    Da ich ja von aussen auf den Thread keinen einfluss habe, wollte ich einfach dieses Sendeevent selber ausloesen. Das geht eigentlich wunderbar und hab ich schon einmal verwendet um mein Programm zu benachrichtigen, dass was passiert ist.

    Jetzt hab ich aber mein Programm vollstaendig umgeplant! Jetzt mach ich eine Klasse (vorher warn es 2) und ich steuere den Zugriff auf die serielle Schnittstelle mit einem Mutex.

    Somit brauch ich nur das Empangsevent... und alles wird etwas leichter...

    mfg

    Bastian
     

Ähnliche Themen

  1. [C#] Form hängt trotz Auslagerung in anderen Thread
    Von real-insanity im Forum .NET Windows Forms
    Antworten: 10
    Letzter Beitrag: 28.09.11, 15:44
  2. Antworten: 1
    Letzter Beitrag: 28.01.11, 20:14
  3. JFrame repaint durch anderen Thread blockiert
    Von Fabiian im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 1
    Letzter Beitrag: 19.10.10, 23:45
  4. Wert von einem Fenster zum anderen übergeben
    Von Michael12345 im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 1
    Letzter Beitrag: 07.04.07, 12:03
  5. Antworten: 1
    Letzter Beitrag: 28.02.04, 00:15

Stichworte