Red Lion DA30D, parsing binary string to (u)INT16/32/48, Float32, Bit16

Another thing... While reading out the port data, in parallel to decoding this into integers and floats, I'd like to append the raw port data to a string variable, which i can store to a tag to have the raw data captured. I guess HEX could be a suitable format for this...

The below HEX string is a LNAV payload, which I convert to bytes and send to the RedLion for testing, using Python. I'd like the raw data tag generated by the RedLion to have the same content if possible.

Python:
hex_string = '8C94ED100000BEE9004943DE67FF90000000E7032200EBFF31000000FFFF040000000000000032007D00FCFFE4F9503E7A354F3E8AAFB343722A1A3E02CDBA3C5361BB3CB31C7B3F1713593C2EDB4C3CFEE2B343CE51183C98FF'
data = bytearray.fromhex(hex_string)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(data, ('192.168.100.100', 8002))
 
I can get each INT48 or INT32 data converted to HEX and stored to a string using IntToText(data, 16, xx), but due to the endianess when collecting the integers from the port, the HEX components are in revered order... Is there are simple way to reverse a string in RedLion? Or any other idea..
Code:
int ReadPortInt48(int port);
{
    int data;
    data  = PortRead(port, 0) << 0;
    data |= PortRead(port, 0) << 8;
    data |= PortRead(port, 0) << 16;
    data |= PortRead(port, 0) << 24;
    data |= PortRead(port, 0) << 32;
    data |= PortRead(port, 0) << 40
    return data;
}

int ReadPortInt32(int port);
{
    int data;
    data  = PortRead(port, 0) << 0;
    data |= PortRead(port, 0) << 8;
    data |= PortRead(port, 0) << 16;
    data |= PortRead(port, 0) << 24;
    return data;
}

tmp = ReadPortInt64(port);
raw = IntToText(tmp, 16, 12);                      
ROV_NAV.Lat = tmp*scale;

tmp = ReadPortInt32(port);
raw += IntToText(tmp, 16, 8);                      
ROV_NAV.Lat = tmp*scale;

tmp = ReadPortInt32(port);
raw += IntToText(tmp, 16, 8);                      
ROV_NAV.Lon = tmp*scale;

ROV_NAV.raw = raw;

The below gives me ROV_NAV.raw = '000010ED948C4900E9BEFF67DE43' while the data sent to RedLion is '8C94ED100000BEE9004943DE67FF' - As seen its is shuffled around by the way i store it when receiving... Can I do somethink smart to shuffle around this either way?

Thanks
 
note that it is the HEX byte components that are in reversed (e.g. the first and last bytes of the red INT32 are still 49 and BE, not 94 and EB).

Since IntToText is it part of Crimson, you will have to either wrap it with something that reverses the hex pairs in each returned string, or write something of your own to do the equivalent but that returns the LSB first.
 
Another option would be to code a wrapper around PortRead, that builds the raw string on the fly, byte by byte, as each call to PortRead is made.
 
Another option would be to code a wrapper around PortRead, that builds the raw string on the fly, byte by byte, as each call to PortRead is made.
I was intending to do this, but RedLion only allows me to have one return value for a function, and i need to send the combined decoded Int as return as well, so could not send the raw data as return simultaneously...
 
I was intending to do this, but RedLion only allows me to have one return value for a function, and i need to send the combined decoded Int as return as well, so could not send the raw data as return simultaneously...
Make the raw data global, or pass the raw data in as a reference, and modify them in the routine. Passing in a -1 for the period to the wrapper could be the trigger to clear the string.
 
I'm back, with another problem :)

Reading a 64 bit float from a Raw UDP/IP port causes problems. I've been trying to stuff the bytes into an integer tag, and make use of another tag of float type, pointing to this integer tag - This was the solution I got for parsing 32 bit Floats, which worked well. Unfortunately it does not work for the 64 bit float..

Is there a mathematical approach I can take to get this solved?

The below does obviously not work.

C#:
int ReadPortInt64(int port);
{
    int data;
    data  = PortRead(port, 0) << 0;
    data |= PortRead(port, 0) << 8;
    data |= PortRead(port, 0) << 16;
    data |= PortRead(port, 0) << 24;
    data |= PortRead(port, 0) << 32;
    data |= PortRead(port, 0) << 40
    data |= PortRead(port, 0) << 48;
    data |= PortRead(port, 0) << 56;
    return data;
}

KM_BINARY.Lat_raw = ReadPortInt64(port);    // RAW INTEGER TAG POINTING TO FLOAT TAG
KM_BINARY.Lon_raw = ReadPortInt64(port);    // RAW INTEGER TAG POINTING TO FLOAT TAG
 
I think i got it working with the R64ToReal now.. With the reversed order of the 32 bit integers into the array - Does this look ok?

C#:
int ReadPortInt32(int port);
{
    int data;
    data  = PortRead(port, 0) << 0;
    data |= PortRead(port, 0) << 8;
    data |= PortRead(port, 0) << 16;
    data |= PortRead(port, 0) << 24;
    return data;
}

// NOT WORKING, CONVERSION FAILES
Array[0] = ReadPortInt32(port);
Array[1] = ReadPortInt32(port);
KM_BINARY.Lat = R64ToReal(Array[0]);

// CHANGING ORDER OF INTEGERS IN ARRAY MAKES IT WORK
Array[1] = ReadPortInt32(port);
Array[0] = ReadPortInt32(port);
KM_BINARY.Lat = R64ToReal(Array[0]);
 
Last edited:
That is interesting: the bytes read by PortRead are in LSByte-First order, but the Crimson two-element array form for 64-bit floats is MSHalf-first. Do you know what type of CPU is in the host that is running Crimson?

And yes, there is a mathematical approach that is similar to the one proposed for 32-bit floats, but
  • there is no 64-bit atomic float in Crimson, and
  • you already have it working
so no need to go into that. The floating-point website mentioned earlier could be used to confirm the format, or if you want to post the values of 8 bytes here I can easily check what the equivalent 64-bit floating value should be.

Something to consider:

The R64ToReal function converts the 64-bit float to a 32-bit float, so (i) precision may be lost and (ii) it is possible that the 64-bit float, with a range of order 10±308, can overflow the 32-bit float. However, the Crimson manual has a bevy "R64" functions, i.e. that add, subtract, return the sine, cosine, base-10 and base-e exponent and logarithm, take comparisons, etc., of the 64-bit floats in that integer array form (Array[1] and Array[0]). So, except where you want to display the value, there is no need to convert it to a REAL; you can instead perform any 64-bit calculations within Crimson using that integer array form.
 

Similar Topics

I need a CQM1H-CPU51 to talk to my Red lion Da30D i just need to read the status of some I/O and maybe read some data registers but I cannot...
Replies
7
Views
1,160
good morning all I have several red lion da30d using crimson 3.0 on the controls network in the plant. I am thinking about getting the AB power...
Replies
3
Views
2,168
We have two Red Lion DA30D units that keep dropping off the network. They are configured as 10.4.7.1 and 10.4.7.2 they work for so long then just...
Replies
24
Views
12,452
While they came up quickly with a fix for the alarm date issue quickly I will have to drive around for a week or so, burning up a lot of fuel...
Replies
4
Views
267
From the Red Lion website, after some customer enquiries in the last week or so... Rev. March 25, 2024 [18:30] Just thought it might help a...
Replies
9
Views
279
Back
Top Bottom