Chriis - 2016-09-26

Hallo,

kurz zu meinen Geräten:
Ich besitze einen Raspberry 3 mit einem PIXtend-Board und einen Schrittmotor inklusive Motoransteuerung (Trinamic TMCM 1161).

Mein Problem dabei ist .... ich möchte den Motor über die PIXtend RS232-Schnittstelle mit den dazugehörigen Befehlen ansprechen. Der Motor selbst besitzt eine eigene Programmiersprache, jedoch kann ich den Motor sowohl über ASCII, als auch mit Bytes ansprechen. Ich hab mittlerweile zu Testzwecken ein Testprogramm vom CodeSys-Forum heruntergeladen, welches auch soweit wunderbar funktioniert mit einem RS232toUSB-Converter über Terminalprogramme am PC.

Sobald ich die RS232-Schnittstelle an den Motor anschließe und ihn versuch anzusteuern reagiert er überhaupt nicht. Sobald ich den Motor über ein Terminalprogramm mithilfe des RS232toUSB-Converter mit Befehlen anspreche führt er auch diese gewünschte Aktion aus. Ich habe danach sowohl das Signal des Terminalprogramms, als auch das RS232-Signal des PIXtend anhand eines Oszilloskop überprüft. Der Motor selbst steht zurzeit im ASCII-Modus, welcher über ASCII-Befehle direkt angesprochen werden kann.

Dabei unterschieden sich das Signal des Terminalprogramms vom Signals der RS232-Schnittstelle erheblichst. Die Frage dabei ist nur warum das so einen Unterschied macht obwohl ich jeweils eine Zeichenkette von ca. 10 Zeichen jeweils als Befehl eingebe? Wo liegt dabei mein Fehler um den Motor ansprechen zu können? bzw. Was muss ich dabei am Quellcode ändern um den Motor im ASCII-Modus ansprechen zu können? Ich bin noch halbwegs Anfänger was die ST-Programmiersprache angeht, daher bitte ich etwas um Eure Unterstützung.

Oder hat jemand schonmal Erfahrungen gemacht mit einem Motor von Trinamic bzw. mit Befehle senden über RS232-Schnittstelle?


Die Zeichenkette beläuft sich dabei auf z.B. AROR 0, 50

Das Testprogramm beinhaltet folgenden Quellcode:

Mit den Einstellungen 9600 Baud, 8 Datenbits, kein Paritätsbit und 1 Stopbit.

VAR_INPUT
   slMode: SERIAL_LINE_MODE;
   udiPort: UDINT;
   udiBaudrate: UDINT;
   sbStopBits: COM.STOPBIT:= COM.STOPBIT.ONESTOPBIT;
   paParity: COM.PARITY:= COM.PARITY.EVEN;
   sWriteText: STRING:= 'AROR 0, 50';
   udiByteSize: UDINT;
END_VAR
VAR_OUTPUT
   sReadText: STRING;
   errError: COM.ERROR;
   xReadSuccess: BOOL;
   xWriteSuccess: BOOL;
   xClosed: BOOL:= TRUE;
END_VAR
VAR
   iState: INT;
   tTimer: TON;
   comOpen: COM.Open; (* Instance of the function block for opening a port *)
   hCom: CAA.HANDLE; (* handle of the port*)
   aParameter: ARRAY [1..7] OF COM.PARAMETER;
   comWrite: COM.Write;   (* Instance of the Write function  block *)
   bWriteBuffer: ARRAY [1..80] OF BYTE; (*Used to write data to the serial port*)
   szWrite: CAA.SIZE;
   comRead: COM.Read; (* Instance of the Read function block *)
   bReadBuffer: ARRAY [1..80] OF BYTE; (*Used to read data from the serial port*)
   szRead: CAA.SIZE;
   comClose: COM.Close; (* Instance of the function block for closing a port *)
END_VAR
CASE iState OF
   
   0:   // The parameter for the COM Ports are set
      aParameter[1].udiParameterId:= COM.CAA_Parameter_Constants.udiPort;
      aParameter[1].udiValue:= udiPort;
      aParameter[2].udiParameterId:= COM.CAA_Parameter_Constants.udiBaudrate;
      aParameter[2].udiValue:= udiBaudrate;      
      aParameter[3].udiParameterId:= COM.CAA_Parameter_Constants.udiStopBits;
      aParameter[3].udiValue:= sbStopBits;
      aParameter[4].udiParameterId:= COM.CAA_Parameter_Constants.udiParity;
      aParameter[4].udiValue:= paParity;
      aParameter[5].udiParameterId:= COM.CAA_Parameter_Constants.udiTimeout;
      aParameter[5].udiValue:= 0;
      aParameter[6].udiParameterId:= COM.CAA_Parameter_Constants.udiBinary;
      aParameter[6].udiValue:= 0;
      aParameter[7].udiParameterId:= COM.CAA_Parameter_Constants.udiByteSize;
      aParameter[7].udiValue:= udiByteSize;
      
      iState:= 1;
      
   1:   //First the COM Port is opened
      comOpen(xExecute:= TRUE, usiListLength:= SIZEOF(aParameter) / SIZEOF(COM.PARAMETER), pParameterList:= ADR(aParameter), hCom=> hCom);
      xClosed:= FALSE;
      IF comOpen.xDone THEN
         comOpen(xExecute:= FALSE);
         //depending on the mode the state for reading or writing is set
         IF slMode = SL_READ OR slMode = SL_READWRITE THEN
            iState:= 2;
         ELSIF slMode = SL_WRITE THEN
            iState:= 4;
         END_IF
      ELSIF comOpen.xError THEN
         errError:= comOpen.eError;
         comOpen(xExecute:= FALSE);
         iState:= 32767;
      END_IF
      
   2: //The reading process is started
      comRead(xExecute:= TRUE, hCom:= hCom, pBuffer:= ADR(bReadBuffer), szBuffer:= SIZEOF(bReadBuffer));
      IF comRead.xDone THEN
         szRead:= comRead.szSize;
         //check if the Port has send something
         IF szRead > 0 THEN
            //the text from the read buffer is saved in the sReadText variable
            MEM.MemMove(ADR(bReadBuffer), ADR(sReadText), UDINT_TO_UINT(szRead));
            MEM.MemFill(ADR(sReadText) + UDINT_TO_UINT(szRead), 1, 0);
            xReadSuccess:= TRUE;
         END_IF
         // the flag has to be set to false, that in the next cylce, the read task will start again, by setting it to true
         comRead(xExecute:= FALSE);
         iState:= 3;
      ELSIF comRead.xError THEN
         errError:= comRead.eError;
         comRead(xExecute:= FALSE);
         iState:= 32767;
      END_IF
      
   3: //After the reading process is finished, a timer is started for waiting 250 milliseconds
      tTimer(IN:= TRUE, PT:= T#250MS);
      IF tTimer.Q THEN
         tTimer(IN:= FALSE);
         xReadSuccess:= FALSE;
         IF slMode = SL_READWRITE THEN
            iState:= 4;
         ELSE
            iState:= 2;
         END_IF
      END_IF
      
   4: // the writing process is started
      IF NOT comWrite.xExecute THEN
         szWrite:= INT_TO_UDINT(LEN(sWriteText));
         //write the string to the buffer for the COM.WRITE Interface
         MEM.MemMove(ADR(sWriteText), ADR(bWriteBuffer), UDINT_TO_UINT(szWrite));
      END_IF
      comWrite(xExecute:= TRUE, hCom:= hCom, pBuffer:= ADR(bWriteBuffer), szSize:= szWrite);
      IF comWrite.xDone THEN
         // the flag is set to false, that in the next cyle this process is started again, by setting it to true 
         comWrite(xExecute:= FALSE);   
         xWriteSuccess:= TRUE;
         iState:= 5;
      ELSIF comWrite.xError THEN
         errError:= comWrite.eError;
         comWrite(xExecute:= FALSE);   
         iState:= 32767;
      END_IF 
      
   5: //After the writing process is finished, a timer is started for waiting 250 milliseconds
      tTimer(IN:= TRUE, PT:= T#250MS);
      IF tTimer.Q THEN
         tTimer(IN:= FALSE);
         xWriteSuccess:= FALSE;
         IF slMode = SL_READWRITE THEN
            iState:= 2;
         ELSE
            iState:= 4;
         END_IF
      END_IF
      
   6: //Closing the ports
      IF hCom <> 0 THEN
         comClose(xExecute:= TRUE, hCom:= hCom);
         IF comClose.xDone THEN
            comClose(xExecute:= FALSE);
            Fb_Init(FALSE, FALSE);
         ELSIF comClose.xError THEN
            errError:= comClose.eError;
            comClose(xExecute:= FALSE);   
            iState:= 32767;
         END_IF
      ELSE
         Fb_Init(FALSE, FALSE);
      END_IF 
   32767:
      ;
END_CASE
   FirstSerialLine(
      slMode:= SL_READWRITE, 
      udiPort:= 1, 
      udiBaudrate:= 9600,
      paParity:= COM.PARITY.NONE,
      sbStopBits:= COM.STOPBIT.ONESTOPBIT,
      udiByteSize := 8);

Vielen Dank schonmal.

Gruß

Chriis

 

Related

Talk.ru: 1
Talk.ru: 2
Talk.ru: 3
Talk.ru: 5
Talk.ru: 7