Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - FAQ - Zum CC1-Forum - Zum CC-Pro-Forum

Re: Serielle Schnittstelle von mehreren Threads aus Kategorie: Programmierung (von Dietmar Weickert - 8.03.2004 20:12)
Als Antwort auf Re: Serielle Schnittstelle von mehreren Threads aus von Floyd - 8.03.2004 19:34
Ich nutze:
C-Control II Station, OSOPT V3.0
Hallo Florian!

Es ist wie immer sehr schwierig, ein fremdes Programm zu lesen und zu verstehen, noch dazu, wenn
es nicht gerade vor Kommentaren strotzt... ;-)

Ein paar Empfehlungen habe ich dennoch:
1. Tastet euch mit Debug-Statements vorwärts.
2. Erklärt in eurem Programm anhand von Kommentaren die Logik derart, dass auch ein au�en
    Stehender es verstehen würde. Dadurch denkt man wirklich ALLES noch einmal durch und findet
    auf diese Weise oft das Problem.
3. Macht euch eine Grafik, in der ihr den Message-Fluss zwischen den beiden CC2 für euch darstellt.
    Vielleicht erkennt ihr auf diese Weise, wo z.B. beide auf den jeweils anderen warten oder andere
    Daten unterwegs sind, als der Partner braucht.
4. Kommentiert alles (Funktionen, Variablen, Programmteile, etc.) aus, was mit dem Problem nichts
    zu tun hat. Dadurch kann man sich auf die wesentlichen Teile besser konzentrieren.

Beste Grü�e,
Dietmar.


> Hi Dietmar!
> Ich arbeite mit Johannes zusammen, und berichte deshalb nun in seinem Namen von den Ergebnissen.
>
> es ist in der Tat dort ein Fehler unterlaufen, jedoch ändert das leider nichts an der Tatsache...
> es funktioniert immernoch nicht.
> Keine von beiden C-Controls gibt einen Laut von sich...
>
> Der Fehler liegt irgendwoe beim Zurücksenden der Antwort.. Nur haben wir keine Ahnung wo...
>
> Vielen Dank für weitere Hilfe!!
>
> mfg Florian
>
> > Hallo Johannes!
> >
> > Verstehe ich das richtig: Du sendest von einer CC2 "!ack" und wartest auf der anderen CC2 darauf,
> > dass "!sdn" ankommt? Muss es da nicht klemmen?
> >
> > Abgesehen davon: Pfeift eine der beiden CC2 wenigstens einmal, oder passiert einfach gar nichts?
> > Hast du schon versucht, Debug-Ausgaben auf den Displays zu machen?
> >
> > Beste Grü�e,
> > Dietmar.
> >
> >
> > > Moin,
> > > ich habe ein Problem, dass ich unbedingt, am besten noch heute lösen muss, allerdings komme
> > > ich nicht drauf und hoffe, dass ihr mir helfen könnt.
> > >
> > > Mein Quellcode soll das Senden und Empfangen von 4 Long-Werten pro Sendung über die
> > > serielle Schnittstelle von mehreren Threads aus ermöglichen. Leider funktioniert irgend etwas nicht.
> > >
> > > Zur Funktionsweise:
> > > �ber die SEND-Funktion übergebe ich dem Modul "communication_base.c2" einen Command mit 4
> > > Parametern vom Typ Long: z.B. SEND("?xyz", 1000, 2000, 3000, 4000);
> > >
> > > Zum Empfangen gibt es die Funktion GETANSWER, die wie folgt verwendet wird:
> > > wait GETANSWER("?xyz"); //wartet, bis "?xyz empfangen wurde, Parameter werden ignoriert.
> > > oder
> > > communication_base.tData Data
> > > wait GETANSWER2("?xyz", Data);
> > > Data.param1.... //so kommt man dann an die Daten.
> > >
> > > Die ganze Sache funktioniert folgendermaÃ?en: In dem Modul "communication_base.c2" sind Variablen
> > > deklariert, in die beim Aufruf der SEND-Funktion die übergebenden Parameter und der Command
> > > gespeichert werden. Ein Thread, der dort immer läuft, nimmt diese Daten und sendet sie an die
> > > Schittstelle. Da man ja nur 30 Zeichen senden kann, wird insgesamt 4 mal gesendet.
> > > Dieser Thread überwacht auch die eingehenden Daten und schreibt sie ebenfalls in
> > > Variablen, die dann über die GETANSWER-Funktion wieder abgefragt werden können. Beim Empfangen
> > > wird pro Parameter (also 4 mal insgesamt) ein ":" Doppelpunkt als Bestätigung zurückgesendet.
> > >
> > > Nun der Quellcode:
> > >
> > > ----------------- "communication_base.c2" -----------------
> > >       type tData {
> > >          string command;
> > >          long   param1;
> > >          long   param2;
> > >          long   param3;
> > >          long   param4;
> > >          long   busy;
> > >        }
> > >        
> > >        type tHshk {
> > >          string command;
> > >          long   busy;
> > >        }
> > >
> > >        tData Input;
> > >        tData Output;
> > >        int ACKInput[5];
> > >        int ACKWaiting;
> > >        tHshk ACKOutput;
> > >
> > >        function pSplit(byte s[], byte searchfor, string t[]) returns byte {
> > >          byte i,j,x;
> > >          j=0;
> > >          t[0]="";
> > >          for i=0 ... s[31]-1 {
> > >            x=s[i];
> > >            if x==searchfor {
> > >              j=j+1;
> > >              t[j]="";
> > >            }
> > >            else t[j]=t[j] + x;
> > >          }
> > >          return j+1;
> > >        }
> > >
> > >        function SETACK()  returns int{
> > >          wait ACKOutput.busy == 0;
> > >          ACKOutput.command = ":";
> > >          ACKOutput.busy = 1;
> > >        }
> > >
> > >        function SEND(string command, long param1, long param2, long param3,
> > >                      long param4) {
> > >          // Sendet Command mit Parametern
> > >          wait Output.busy == 0;
> > >          Output.command = command;
> > >          Output.param1 = param1;
> > >          Output.param2 = param2;
> > >          Output.param3 = param3;
> > >          Output.param4 = param4;
> > >          Output.busy = 1;
> > >        }
> > >
> > >        function GETANSWER(string command) returns int {
> > >          // Wartet auf Antwort (ohne Parameter-Ã?bergabe)
> > >          if strx.comp(command,Input.command) {
> > >            Input.command = "";
> > >            Input.param1 = 0;
> > >            Input.param2 = 0;
> > >            Input.param3 = 0;
> > >            Input.param4 = 0;
> > >            return -1;
> > >          }
> > >          else {
> > >            return 0; }
> > >        }
> > >
> > >        function GETANSWER2(string command, tData Data) returns int {
> > >          // Wartet auf Antwort (mit Parameter-Ã?bergabe)
> > >          if strx.comp(command,Input.command) {
> > >            Data.param1 = Input.param1;
> > >            Data.param2 = Input.param2;
> > >            Data.param3 = Input.param3;
> > >            Data.param4 = Input.param4;
> > >            Input.command = "";
> > >            Input.param1 = 0;
> > >            Input.param2 = 0;
> > >            Input.param3 = 0;
> > >            Input.param4 = 0;
> > >            return -1;
> > >          }
> > >          else {
> > >            return 0; }
> > >        }
> > >
> > >        function pSend (string command, int number, long parameter) {
> > >          int length;
> > >          string data;
> > >          data = command + " ";
> > >          str.putint(data,number);
> > >          data = data + " ";
> > >          str.putlong(data,parameter);
> > >          length = str.length(data);
> > >          int a;
> > >          for a=length...30  {
> > >            data = data + " ";
> > >          }
> > >          hwcom.send (data, 30);
> > >          wait hwcom.ready();
> > >        }
> > >
> > >        function pSendAck (string command) {
> > >          int a;
> > >          int length;
> > >          length = str.length(command);
> > >          for a=length...30  {
> > >            command = command + " ";
> > >          }
> > >          hwcom.send (command, 30);
> > >          wait hwcom.ready();
> > >        }
> > >
> > >        function pReceiveByte(byte Buf[]) returns int {
> > >          int a;
> > >          for a=0...19 {
> > >            Buf[a] = 0; }
> > >          int returnval;
> > >          returnval = hwcom.receive(Buf, 20, 0);
> > >          return returnval;
> > >        }
> > >
> > >        function pReceive(string myData) returns int {
> > >          int a;
> > >          byte Buf[19];
> > >          int returnval;
> > >          returnval = pReceiveByte(Buf);
> > >          myData = "";
> > >          for a=0...19 {
> > >            str.putchar(myData, Buf[a]); }
> > >          return returnval;
> > >        }
> > >
> > >        thread Communication {
> > >          string rawdata;
> > >          int datalength;
> > >          string command;
> > >
> > >          // ACK senden
> > >          wait hwcom.ready();
> > >          command = ACKOutput.command;
> > >          if ACKOutput.busy == 1 {
> > >             pSendAck(command);
> > >             ACKOutput.command = "";
> > >             ACKOutput.busy = 0;
> > >          }
> > >
> > >          // Daten senden
> > >          wait hwcom.ready();
> > >          command = Output.command;
> > >
> > >          if Output.busy == 1 {
> > >         // sleep 100;
> > >            if (ACKInput[1] == 0) and (ACKWaiting == 0) {
> > >             pSend(command,1,Output.param1);
> > >             ACKWaiting = 1;
> > >            }
> > >            if (ACKInput[1] == 1) and (ACKWaiting == 1) {
> > >             pSend(command,2,Output.param2);
> > >             ACKWaiting = 2;
> > >            }
> > >            if (ACKInput[2] == 1) and (ACKWaiting == 2) {
> > >             pSend(command,3,Output.param3);
> > >             ACKWaiting = 3;
> > >            }
> > >            if (ACKInput[3] == 1) and (ACKWaiting == 3) {
> > >             pSend(command,4,Output.param4);
> > >             ACKWaiting = 4;
> > >            }
> > >            if (ACKInput[4] == 1) and (ACKWaiting == 4) {
> > >             Output.command = "";
> > >             Output.param1 = 0;
> > >             Output.param2 = 0;
> > >             Output.param3 = 0;
> > >             Output.param4 = 0;
> > >             Output.busy = 0;
> > >             ACKInput[0] = 0; ACKInput[1] = 0; ACKInput[2] = 0;
> > >             ACKInput[3] = 0; ACKInput[4] = 0; ACKWaiting = 0;
> > >            }
> > >          }
> > >
> > >          // Empfangen
> > >          wait hwcom.ready();
> > >          string dataset[29];
> > >          int number;
> > >          datalength = pReceive(rawdata);
> > >          if datalength > 0 {
> > >            string ident;
> > >            strx.mid(rawdata,ident,0,1);
> > >            string dp;
> > >            dp = ":";
> > >            if strx.comp(ident, dp) {
> > >              // ACK
> > >              if Output.busy == 1 {
> > >               ACKInput[ACKWaiting] = 1;
> > >              }
> > >            }
> > >            else {
> > >              // Daten
> > >
> > >              pSplit(rawdata,32,dataset);
> > >              number = strx.getNum(dataset[1]);
> > >              if (number == 1) {
> > >                Input.param1 = strx.getNum(dataset[2]);
> > >                SETACK();
> > >              }
> > >              if (number == 2) {
> > >                Input.param2 = strx.getNum(dataset[2]);
> > >                SETACK();
> > >              }
> > >              if (number == 3) {
> > >                Input.param3 = strx.getNum(dataset[2]);
> > >                SETACK();
> > >              }
> > >              if (number == 4) {
> > >                Input.param4 = strx.getNum(dataset[2]);
> > >                strx.mid(rawdata,Input.command,0,4);
> > >                SETACK();
> > >              }
> > >            }
> > >          }
> > >        }
> > >
> > >        function INIT() {
> > >          hwcom.init();
> > >          hwcom.setspeed (8);
> > >          ACKInput[0] = 0; ACKInput[1] = 0; ACKInput[2] = 0;
> > >          ACKInput[3] = 0; ACKInput[4] = 0; ACKWaiting = 0;
> > >          run Communication;
> > >        }

> > >
> > > Das war das Modul. Nun ein Beispiel-Programm, das nicht funktioniert. Es sind zwei Dateien, da
> > > hier zwei CC2 verbunden werden (beide enthalten natürlich das communication-Modul).
> > >
> > > ----------------- "test1.c2" -----------------
> > > function dothebeep(int number) {
> > >     int a;
> > >     for a = 1...number {
> > >       plm.beep (20);
> > >       sleep(5);
> > >       plm.beep (-1);
> > >       sleep(100);
> > >     }
> > > }
> > >
> > > thread main {
> > >   communication_base.INIT();
> > >
> > >   loop{
> > >     wait communication_base.GETANSWER("?ack"); // "?ack" empfangen wird, "!ack" zurücksenden
> > >     communication_base.SEND("!ack", 0,0,0,0);
> > >     dothebeep(2);
> > >   }
> > > }

> > >
> > > ----------------- "test2.c2" -----------------
> > > function dothebeep(int number) {
> > >     int a;
> > >     for a = 1...number {
> > >       plm.beep (20);
> > >       sleep(5);
> > >       plm.beep (-1);
> > >       sleep(100);
> > >     }
> > > }
> > >
> > > thread main {
> > >   lcd.init();
> > >
> > >   loop {
> > >     communication_base.SEND("?ack",0,0,0,0);
> > >     wait communication_base.GETANSWER("!sdn");
> > >     dothebeep(1);
> > >     sleep 1000;
> > >   }
> > > }

> > >
> > > Um ehrlich zu sein bin ich verzweifelt. Der Kram muss morgen laufen...
> > > Ich hoffe, dass sich jemand damit beschäftigen kann, wäre aber meine letzte Rettung.
> > >
> > > GruÃ?
> > > Johannes


    Antwort schreiben


Antworten: