-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Warum bremst SerialPort mein Programm aus?

  1. #1

    Warum bremst SerialPort mein Programm aus?

    Anzeige

    Hallo zusammen,

    erstmal ein par infos über mein projekt. mein bot basiert auf den catwiesel auf dem ein atmega8 mit einem bluetooth modul btm-222 ausgestatt.
    gesteuert wir mein bot per bluetooth per pocketpc, und zwar mit dem g-sensor (neigesensor). die steuerung klappt soweit wunderbar. nun zum problem:

    auf dem pocketpc display möchte ich die werte vom g-sensor anzeigen lassen, das funktioniert auch sehr flüssig. doch sobal der die serielle port geöffnet wird, ruckelt die visualisierung und läuft nicht mehr flüssig. schließ ich den port wieder, ist alles wieder in ordnung.
    die software auf dem pocketpc ist in visual c# programmiert. ich benutze das serialPort-Control. ich vermute, das das control im hintergrund pollt und so mein program ausbremst.

    hat jemand einen tipp für mich?

    gruss
    cetin

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    Die Serial Port class hat zum Teil ihre macken. Aber ohne etwas code kann man kaum was sagen. Ich glaube die Thematik wurde schon mal auf mycsharp.de behandelt. Vielleicht lässt sich ja das was finden

  3. #3
    Hier ist mein Code, es wird in einem Timer alle 5ms gesendet. habe es auch schon mit 100ms usw. probiert, gleiches problem.

    Code:
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using Sensors;
       
    namespace G_Sensor
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            bool Freigabe = false;
            IGSensor mySensor = GSensorFactory.CreateGSensor();
    
            private void myTimer_Tick(object sender, EventArgs e)
            {
                GVector myVector = mySensor.GetGVector();
                bool DeadZone = true; 
                string Fahrtrichtung = "", Lenkrichtung = "", RichtungKetteLinks = "", RichtungKetteRechts = "";
                Int16 GeschwindigkeitKetteLinks = 0, GeschwindigkeitKetteRechts = 0;
                double VerteilungKetteLinks = 0, VerteilungKetteRechts = 0;
                double X = Math.Abs(myVector.X * 10000);
                double Y = Math.Abs(myVector.Y * 10000);
                double XMax = 80000;
                double YMax = 50000;
    
                if (X > XMax) X = XMax;
                if (Y > YMax) Y = YMax;
    
                if (myVector.X < 1 && myVector.X > -1 && myVector.Y < 1 && myVector.Y > -1)DeadZone = true;else DeadZone = false;
                                
                if (myVector.X >= 1) Fahrtrichtung = "Vor";
                if (myVector.X <= -1) Fahrtrichtung = "Zurück";
                if (myVector.Y >= 1) Lenkrichtung = "Rechts";
                if (myVector.Y <= -1) Lenkrichtung = "Links";
                if (myVector.X < 1 && myVector.X > -1) Fahrtrichtung = "Drehen";
    
                VerteilungKetteLinks = X;
                VerteilungKetteRechts = X;
    
                if (Fahrtrichtung == "Vor")
                {
                    RichtungKetteLinks = "Vor";
                    RichtungKetteRechts = "Vor";
                }
    
                if (Fahrtrichtung == "Zurück")
                {
                    RichtungKetteLinks = "Zurück";
                    RichtungKetteRechts = "Zurück";
                }
                
                if (Lenkrichtung == "Links")
                {
                    VerteilungKetteLinks = Y / 2;
                    VerteilungKetteRechts = Y / 2;
                    if((XMax-X)<VerteilungKetteRechts)
                    {
                        VerteilungKetteRechts = VerteilungKetteRechts - (XMax - X);
                        VerteilungKetteLinks = Y - VerteilungKetteRechts;
                    }
                    VerteilungKetteLinks = X - VerteilungKetteLinks;
                    VerteilungKetteRechts = X + VerteilungKetteRechts;
                    if (VerteilungKetteLinks < 0) VerteilungKetteLinks = 0;
                }
    
                if (Lenkrichtung == "Rechts")
                {
                    VerteilungKetteLinks = Y / 2;
                    VerteilungKetteRechts = Y / 2;
                    if ((XMax - X) < VerteilungKetteLinks)
                    {
                        VerteilungKetteLinks = VerteilungKetteLinks - (XMax - X);
                        VerteilungKetteRechts = Y - VerteilungKetteLinks;
                    }
                    VerteilungKetteRechts = X - VerteilungKetteRechts;
                    VerteilungKetteLinks = X + VerteilungKetteLinks;
                    if (VerteilungKetteRechts < 0) VerteilungKetteRechts = 0;
                }
    
                Int16 PWM_Min=115, PWM_Max=255;
                double Steigung, Y_Achsenabschnitt;
                Steigung = (XMax - 10000) / (PWM_Max - PWM_Min);
                Y_Achsenabschnitt = XMax - (Steigung * PWM_Max);
    
                GeschwindigkeitKetteLinks = (Int16)((Math.Abs(VerteilungKetteLinks) - Y_Achsenabschnitt) / Steigung);
                GeschwindigkeitKetteRechts = (Int16)((Math.Abs(VerteilungKetteRechts) - Y_Achsenabschnitt) / Steigung);
    
                if (DeadZone == true)
                {
                    GeschwindigkeitKetteLinks = 0;
                    GeschwindigkeitKetteRechts = 0;
                }
    
                if (Freigabe == true)
                {
                    string a="", b="", c="", d="";
                    if (VerteilungKetteLinks < 0 && Fahrtrichtung =="Drehen") RichtungKetteLinks = "Zurück";
                    if (VerteilungKetteRechts < 0 && Fahrtrichtung == "Drehen") RichtungKetteRechts = "Zurück";
                    if (VerteilungKetteLinks > 0 && Fahrtrichtung == "Drehen") RichtungKetteLinks = "Vor";
                    if (VerteilungKetteRechts > 0 && Fahrtrichtung == "Drehen") RichtungKetteRechts = "Vor";
    
                    if (RichtungKetteRechts == "Vor") a = "1";
                    if (RichtungKetteLinks == "Vor") c = "1";
                    if (RichtungKetteRechts == "Zurück") a = "0";
                    if (RichtungKetteLinks == "Zurück") c = "0";
                    b = GeschwindigkeitKetteRechts.ToString("000");
                    d = GeschwindigkeitKetteLinks.ToString("000");  
                    serialPort1.Write(a + b + c + d + "\r");
                }
            }
    
            private void menuItem1_Click_1(object sender, EventArgs e)
            {
                serialPort1.Close();  
                mySensor.Dispose();
                mySensor = null; 
                Close(); 
            }
    
            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                if ((e.KeyCode == System.Windows.Forms.Keys.Up))
                {
                    // Up
                }
                if ((e.KeyCode == System.Windows.Forms.Keys.Down))
                {
                    // Down
                }
                if ((e.KeyCode == System.Windows.Forms.Keys.Left))
                {
                    // Left
                }
                if ((e.KeyCode == System.Windows.Forms.Keys.Right))
                {
                    // Right
                }
                if ((e.KeyCode == System.Windows.Forms.Keys.Enter))
                {
                    // Enter
                }
    
            }
    
            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                Freigabe = true;
                pictureBox1.BackColor = Color.LimeGreen;   
            }
    
            private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
            {
                Freigabe = false;
                serialPort1.Write("10001000\r");
                pictureBox1.BackColor = Color.White;
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {            
                serialPort1.PortName = "COM2";
                serialPort1.Open();
                serialPort1.Write("10001000\r");
            }
        }
    }

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    schon mal versucht den port zu öffen, nen string zu schreiben und dann wieder zu schließen. Hängt das Programm dann immer noch ?
    Ich hab das ganze nur kurz überflogen. Du machst halt doch einige Berechnungen innerhalb von myTimer_Tick.

    Versuch vllt auch noch am Ende von myTimer_Tick den serialport zu schließen und zu Beginn dann halt auch auf zu machen

  5. #5
    das problem ist, das jedes mal wenn ich den port öffne, bekomme ich von windows mobile 6.5 ein dialog, wo ich nochmal den com-port von hand bestätigen. Deshalb wird das schließen und das erneute öffnen nicht machbar sein.

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    Funktionieren unter windows mobile 6.5 Threads, wenn ja lager das ganze in einen extra Thread aus dann sollte das ganze keine einwirkung mehr auf deine GUI haben

  7. #7
    wie meinst du das mit dem thread, kannst du mal ein beispiel geben?

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.06.2009
    Beiträge
    1.265
    du weist was Threading ist ?
    http://www.devtrain.de/news.aspx?artnr=790

    Threads werden quasi "parallel" ausgeführt. Zumindest gaukelt einem das Betriebssystem das vor. Sprich wenn du den Teil der dir alles zum stocken bringt, dein Zugriff auf den Serialport in einen Thread auslagert, sollte deine GUI ohne stocken weiterlaufen.

    In C# würde das ganze dann in etwa so aussehen

    System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(Methode));

    void Methode()
    {
    Das hier wird in einem anderen Thread ausgeführt als deine GUI

    }

    Was du beachten solltest dass bevor du auf irgendwelche GUI Controls aus dem neuen Thread zugreifst diese Invoken musst.

    Aber dafür gibt auch einige Tutorials im Internet

  9. #9
    Hab das jetzt mit nem zweiten thread gemacht und spreche per invoke mein label1 an. aber der tread wird nur einmal ausgeführt. ich denke nicht dass ich eine endlosschleife in den zweiten thread erstellen muss, oder?

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    eine Frage:

    was zum geier machst du in dieser mörderischen timer-methode O_o (ich möchte es wirklich unbedingt wissen!!! weil cih es nicht verstehe und dort aber dein problem sehe)

    wie kommst du auf auslesen, du verwendest nirgendwo ein read, nur write open und close, dein programm passt nicht ganz zu deiner frage!

    oder kannst du eventuell noch code zu "mySensor.GetGVector () ; " präsentieren ?


    generell würde ich dir 3 dinge empfehlen:

    1. verwende doch bitte "ereignisse" (interrupts) ... jeder knopfdruck kann ein ereignis und damit verbunden eine methode auslösen

    2. schau dir bitte nochmal exakt an wie du deinen com-port konfiguriert hast, handshake hast du hoffentlich ausgeschalten, oder braucht dein Funkmodul das ?!

    3. schau mal ob dein GSensor irgendwelche ereignisse anbietet und verwende die statt deines timers .... timer sind allgemein verpönt um regelmäßige aufgaben zu erfüllen ... "wenn man timer verwendet hat, war man nur zu faul sich einen vernünftigen zustandsaautomaten auszudenken, timer sollten nur für delays oder timeouts verwendet werden" hat mein dozent immer gesagt

    PS: DOCH! die run methode die du im 2ten thread überschrieben hast muss eine endlossschleife sein, die man über eine spezielle variable allerdings beenden kann, damit man den thread wieder auf wunsch beenden kann. Threads per close/shutdown zu beenden ist unschön und kann speicherlecks hinterlassen

    PS zum synchronisieren kannst du deine threads in den sleep schicken und sie per interrupt befehl aufwecken, aber threads halte ich für diese eine aufgabe für übertrieben, versuchs doch lieber nocheinmal mit optimierungen am programm selber

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •