Hello everyone,
I had to get the sensor I used for an application I made for rs 422, but since the X90CP154_60_00 controller I use supports rs232, I use a converter every now and then. When I look at the sensor’s own interface, I can record at a recording speed of 400 Hz and above without repeating the data, but in the recordings I receive on the Automation Studio side, I get a recording result of 30 Hz and around, the data repeats very often.
I would be very grateful if you can check my communication code I shared below and suggest me a solution. Sincerely regards.
#include <bur/plctypes.h>
#include <stdint.h>
#ifdef _DEFAULT_INCLUDES
#include <AsDefault.h>
#endif
int findSequenceIndices(const uint8_t* array, int size) {
int i;
for (i = 0; i < size - 1; i++) {
if (array[i] == 170 && array[i + 1] == 85) { // Check if the sequence matches
return i; // Store the index
}
}
return -1;
}
int16_t to_signed_16bit(uint8_t msb, uint8_t lsb) {
int16_t value = (lsb << 8) | msb;
return value >= 0x8000 ? value - 0x10000 : value;
}
uint16_t to_unsigned_16bit(uint8_t msb, uint8_t lsb) {
return (lsb << 8) | msb;
}
void _INIT ProgramInit(void){
Receiver.Commands.open_receive = 1;
}
void _CYCLIC ProgramCyclic(void){
switch (Receiver.step) {
case FRM_WAIT:
if (Receiver.Commands.open_receive == 1) {
Receiver.step = FRM_OPEN;
}
break;
case FRM_OPEN:
// Call the FRM_xopen function block
Receiver.FRM_xopen_0.enable = 1;
Receiver.FRM_xopen_0.device = (UDINT)DeviceName;
Receiver.FRM_xopen_0.mode = (UDINT)DeviceConfig;
Receiver.FRM_xopen_0.config = &(Receiver.xopenConfig);
FRM_xopen(&Receiver.FRM_xopen_0);
if (Receiver.FRM_xopen_0.status == 0) {
Receiver.step = FRM_READ;
} else if (Receiver.FRM_xopen_0.status == BUSY) {
Receiver.step = FRM_OPEN;
} else {
Receiver.step = FRM_ERROR;
}
break;
case FRM_READ:
Receiver.FRM_read_0.enable = 1;
Receiver.FRM_read_0.ident = Receiver.FRM_xopen_0.ident;
FRM_read(&Receiver.FRM_read_0);
if (Receiver.FRM_read_0.status == 0) {
if (Receiver.FRM_read_0.buflng <= sizeof(Receiver.receive_data)) {
memcpy(Receiver.receive_data, Receiver.FRM_read_0.buffer, Receiver.FRM_read_0.buflng);
int indices = findSequenceIndices(Receiver.receive_data, Receiver.FRM_read_0.buflng);
if (indices >= 0) {
KernelRawData.Heading = to_unsigned_16bit(Receiver.receive_data[8], Receiver.receive_data[9]);
KernelRawData.Pitch = to_signed_16bit(Receiver.receive_data[10], Receiver.receive_data[11]);
KernelRawData.Roll = to_signed_16bit(Receiver.receive_data[12], Receiver.receive_data[13]);
Heading = (double)KernelRawData.Heading / 100.0;
Pitch = (double)KernelRawData.Pitch / 100.0;
Roll = (double)KernelRawData.Roll / 100.0;
} else {
// Eşleşme bulunamadı, hata işleme
Receiver.step = FRM_ERROR;
}
} else {
// Buffer boyutu yetersiz, hata işleme
Receiver.step = FRM_ERROR;
}
Receiver.step = FRM_RBUF;
} else if (Receiver.FRM_read_0.status == frmERR_NOINPUT) {
Receiver.step = FRM_READ;
} else {
Receiver.step = FRM_ERROR;
}
break;
case FRM_COPY_RD_DATA:
memset(Receiver.receive_data, 0, sizeof(Receiver.receive_data));
memcpy(Receiver.receive_data, Receiver.FRM_read_0.buffer, Receiver.FRM_read_0.buflng);
indices = findSequenceIndices(Receiver.receive_data, sizeof(Receiver.receive_data));
// if(indices>=0){
KernelRawData.Heading = to_unsigned_16bit(Receiver.receive_data[8], Receiver.receive_data[9]);
KernelRawData.Pitch = to_signed_16bit(Receiver.receive_data[10] , Receiver.receive_data[11]);
KernelRawData.Roll = to_signed_16bit(Receiver.receive_data[12] , Receiver.receive_data[13]);
Heading = (double)KernelRawData.Heading / 100.0;
Pitch = (double)KernelRawData.Pitch / 100.0;
Roll = (double)KernelRawData.Roll / 100.0;
// }
Receiver.step = FRM_RBUF;
break;
case FRM_RBUF:
Receiver.FRM_rbuf_0.enable = 1;
Receiver.FRM_rbuf_0.ident = Receiver.FRM_xopen_0.ident;
Receiver.FRM_rbuf_0.buffer = Receiver.FRM_read_0.buffer;
Receiver.FRM_rbuf_0.buflng = Receiver.FRM_read_0.buflng;
FRM_rbuf(&Receiver.FRM_rbuf_0);
if (Receiver.FRM_rbuf_0.status == 0) {
if (Receiver.Commands.close == 1) {
Receiver.Commands.open_receive = 0;
Receiver.step = FRM_CLOSE;
} else {
Receiver.step = FRM_READ;
}
} else if (Receiver.FRM_rbuf_0.status == BUSY) {
Receiver.step = FRM_RBUF;
} else if (Receiver.FRM_rbuf_0.status == frmERR_INVALIDBUFFER) {
Receiver.step = FRM_READ;
} else {
Receiver.step = FRM_ERROR;
}
break;
case FRM_CLOSE:
Receiver.FRM_close_0.enable = 1;
Receiver.FRM_close_0.ident = Receiver.FRM_xopen_0.ident;
FRM_close(&Receiver.FRM_close_0);
if (Receiver.FRM_close_0.status == 0) {
Receiver.Commands.close = 0;
Receiver.step = FRM_WAIT;
} else if (Receiver.FRM_close_0.status == BUSY) {
Receiver.step = FRM_CLOSE;
} else {
Receiver.step = FRM_ERROR;
}
break;
case FRM_ERROR:
break;
default:
break;
}
}
PROGRAM _INIT
Receiver.Commands.open_receive := TRUE;
END_PROGRAM
PROGRAM _CYCLIC
CASE Receiver.step OF
FRM_WAIT: (*--- wait for command*)
IF Receiver.Commands.open_receive = TRUE THEN (*command for Receiver activation*)
Receiver.step := FRM_OPEN;
END_IF
(*close will be requested in step FRM_RBUF*)
FRM_OPEN: (*--- open serial interface*)
(*Parameters for FRM_xopen()*)
Receiver.FRM_xopen_0.enable := TRUE;
Receiver.FRM_xopen_0.device := ADR('IF1'); (*Devicename --> see your serial interface properties*)
Receiver.FRM_xopen_0.mode := ADR('/PHY=RS232 /BD=115200 /DB=8 /PA=N /SB=1'); (*Modestring --> specifies the seria operation mode*)
Receiver.FRM_xopen_0.config := ADR(Receiver.xopenConfig) ; (*Additional Parameters, optional*)
(*Additional Parameters for FRM_xopen()*)
// Receiver.xopenConfig.idle := 10; (*Idle time between two characters*)
// Receiver.xopenConfig.delimc := 0; (*activate two delimeters*)
// Receiver.xopenConfig.delim[0] := 0; (*e.g. CR - carridge return -> dec 13*)
// Receiver.xopenConfig.delim[1] := 0; (*e.g. LF - line feed -> dec 10*)
// Receiver.xopenConfig.tx_cnt := 3; (*number of transmit buffers*)
// Receiver.xopenConfig.rx_cnt := 3; (*number of receive buffers*)
// Receiver.xopenConfig.tx_len := 256; (*length of transmit buffers*)
// Receiver.xopenConfig.rx_len := 256; (*lenght of receive buffers*)
// Receiver.xopenConfig.argc := 0; (*activate additional options*)
// Receiver.xopenConfig.argv := 0; (*parameters for additional options (check help)*)
Receiver.FRM_xopen_0(); (*call the FRM_xopen() function*)
IF Receiver.FRM_xopen_0.status = 0 THEN
Receiver.step := FRM_READ; (*Interface opend successfully --> next step*)
ELSIF Receiver.FRM_xopen_0.status = BUSY THEN
Receiver.step := FRM_OPEN; (*operation not finished yet --> call again*)
ELSE
Receiver.step := FRM_ERROR; (*function returned errorcode --> check help*)
END_IF
FRM_READ: (*--- read data from serial interface*)
Receiver.FRM_read_0.enable := TRUE;
Receiver.FRM_read_0.ident := Receiver.FRM_xopen_0.ident;
Receiver.FRM_read_0(); (*call the FRM_read() function*)
IF Receiver.FRM_read_0.status = 0 THEN
Receiver.step := FRM_COPY_RD_DATA; (*system returned a valid data --> next step*)
ELSIF Receiver.FRM_read_0.status = frmERR_NOINPUT THEN
Receiver.step := FRM_READ; (*no data available --> call again*)
ELSIF Receiver.FRM_read_0.status = frmERR_INPUTERROR THEN
Receiver.step := FRM_RBUF; (*received Frame with defective characters, skip data*)
ELSE
Receiver.step := FRM_ERROR; (*function returned errorcode --> check help*)
END_IF
FRM_COPY_RD_DATA: (*--- copy data out of the receive buffer*)
memset(ADR(Receiver.receive_data),0,300); (*clear read_data buffer*)
memcpy(ADR(Receiver.receive_data),Receiver.FRM_read_0.buffer,Receiver.FRM_read_0.buflng); (*copy and evaluate read data*)
Receiver.step := FRM_RBUF; (*release read buffer*)
FRM_RBUF: (*--- release readbuffer*)
(*Parameters for FRM_rbuf()*)
Receiver.FRM_rbuf_0.enable := TRUE;
Receiver.FRM_rbuf_0.ident := Receiver.FRM_xopen_0.ident; (*ident from FRM_xopen()*)
Receiver.FRM_rbuf_0.buffer := Receiver.FRM_read_0.buffer; (*read buffer*)
Receiver.FRM_rbuf_0.buflng := Receiver.FRM_read_0.buflng; (*length of sendbuffer*)
Receiver.FRM_rbuf_0(); (*call the FRM_rbuf() function*)
IF Receiver.FRM_rbuf_0.status = 0 THEN
IF Receiver.Commands.close = TRUE THEN
Receiver.Commands.open_receive := FALSE; (*disable command open_send*)
Receiver.step := FRM_CLOSE; (*request to close serial port*)
ELSE
Receiver.step := FRM_READ; (*read again*)
END_IF
ELSIF Receiver.FRM_rbuf_0.status = BUSY THEN
Receiver.step := FRM_RBUF; (*operation not finished yet --> call again*)
ELSIF Receiver.FRM_rbuf_0.status = frmERR_INVALIDBUFFER THEN
Receiver.step := FRM_READ; (*buffer is invalid --> read again*)
ELSE
Receiver.step := FRM_ERROR; (*function returned errorcode --> check help*)
END_IF
FRM_CLOSE: (*--- close the interface*)
Receiver.FRM_close_0.enable := TRUE;
Receiver.FRM_close_0.ident := Receiver.FRM_xopen_0.ident; (*ident from FRM_xopen()*)
Receiver.FRM_close_0(); (*call the FRM_close() function*)
IF Receiver.FRM_close_0.status = 0 THEN
Receiver.Commands.close := FALSE; (*disable close command*)
Receiver.step := FRM_WAIT; (*closed interface successfully --> wait step*)
ELSIF Receiver.FRM_close_0.status = BUSY THEN
Receiver.step := FRM_CLOSE; (*operation not finished yet --> call again*)
ELSE
Receiver.step := FRM_ERROR; (*function returned errorcode --> check help*)
END_IF
FRM_ERROR: (*--- error handling*)
; (*not implementet yet, check help for error codes*)
END_CASE
END_PROGRAM
PROGRAM _EXIT
(* Insert code here *)
END_PROGRAM