ASCII control of VFD - controls

All,
I am a new user here, and thought I would see if the experts could help me with something I am new to.
I have been given the following statement to try and solve:
The Variable Frequency Drive (VFD) is connected to the PLC by RS485 communication. The speed of the motor (M2) can be adjusted by sending the following command:
STX N DATA ETX , with each separate value having the <> symbols around them.
Data : Length of data is 1 byte, in which the value of S (Slow), M (Medium) or F (Fast) can be sent.
N : Node number of the VFD, with a data length of two byte ASCII.
My question is, how would I type to send this data? It doesn't say whether to use a specific data type to represent, so surely I could just type the data as it is, e.g. STX 1 S ETX?
Othwerside, I'm not sure how to combine the byte representations of the data, representing them in hex, binary or decimal. I'm not sure what is meant by two byte ASCII, is this not UNICODE-16? Also, I'm not sure if I need to send the values of STX or ETX with the data string or not
I hope someone can shed some light on this.
Thanks in advance.

Since the frequency goes from 0-50 Hz, I think we should send data in this range.
So if we want the frequency to be half maximal, we will send 25.
To send this to VFD, we first need to split that number into 2 and 5
The message should read STX 2 5 ETX?
Now we look at the ASCII code table and find 2 and 5.
0x50 = 2
0x53 = 5
We convey everything in a message that reads
STX 0x50 0x53 ETX
The aforementioned S7-300 is recommended for operation. You can also solve this through his TIA portal.

All,
I managed to figure this out with a bit of digging. I simulated it using Siemens S7-300 on TIA portal, and set up communications on a module. I sent the values I wanted using a "move" block, to a value set in the Data Block.
I repeated this for the Node value, making sure the correct data type was chosen, and sent the data through a Send_ptp command block.
Must have got a bit flustered and tired the other night when I was trying it. Hopefully it might help someone in the future.

Related

Reveng to find out CRC algorithm in closed protocol

I have one machine with closed protocol and another device "gateway Modbus" from the same manufacter. This gateway convert this protocol to RS-485 Modbus.
When I send a command packet (modbus function 16) to gateway, gateway send (converted) specific packet to the machine and when I inject this packet over simple UART communication, machine can understand and change values too. I create a list with some cloned commands, but I need to know how CRC/checksum/etc is calculed (I think) to create custom packets.
I already used RevEng tool (https://reveng.sourceforge.io/) and CRCcalculator (https://crccalc.com/) trying to find some common crc algorithm with cloned packets, but none worked.
Some cloned packets, where 2 last bytes is CRC/etc. In this packets I changed the temperature value from 0x11 to 0x15 and last 2 bytes changed too (maybe crc/checksum/etc):
9A56F1FE0EB9001100000100641C
9A56F1FE0EB90012000001006720
9A56F1FE0EB90013000001006620
9A56F1FE0EB9001400000100611C
9A56F1FE0EB9001500000100601C
RevEng output:
./reveng -w 16 -l -s 9A56F1FE0EB9001100000100641C 9A56F1FE0EB90012000001006720 9A56F1FE0EB90013000001006620 9A56F1FE0EB9001400000100611C 9A56F1FE0EB9001500000100601C
./reveng: no models found
Someone can help me?
It's not a CRC. The second-to-last byte is the exclusive-or sum of the preceding bytes. I'm not sure what the last byte is, but since it is only taking on two different values in your example, it does not appear to be part of a check value. Or if it is, it's a rather ineffective check value algorithm.

How do I interpret a python byte string coming from F1 2020 game UDP packet?

Title may be wildly incorrect for what I'm trying to work out.
I'm trying to interpret packets I am recieving from a racing game in a way that I understand, but I honestly don't really know what I'm looking at, or what to search to understand it.
Information on the packets I am recieving here:
https://forums.codemasters.com/topic/54423-f1%C2%AE-2020-udp-specification/?tab=comments#comment-532560
I'm using python to print the packets, here's a snippet of the output, which I don't understand how to interpret.
received message: b'\xe4\x07\x01\x03\x01\x07O\x90.\xea\xc2!7\x16\xa5\xbb\x02C\xda\n\x00\x00\x00\xff\x01\x00\x03:\x00\x00\x00 A\x00\x00\xdcB\xb5+\xc1#\xc82\xcc\x10\t\x00\xd9\x00\x00\x00\x00\x00\x12\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$tJ\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01
I'm very new to coding, and not sure what my next step is, so a nudge in the right direction will help loads, thanks.
This is the python code:
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 20777
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(4096)
print ("received message:", data)
The website you link to is describing the data format. All data represented as a series of 1's and 0's. A byte is a series of 8 1's and 0's. However, just because you have a series of bytes doesn't mean you know how to interpret them. Do they represent a character? An integer? Can that integer be negative? All of that is defined by whoever crafted the data in the first place.
The type descriptions you see at the top are telling you how to actually interpret that series of 1's and 0's. When you see "unit8", that is an "unsigned integer that is 8 bits (1 byte) long". In other words, a positive number between 0 and 255. An "int8" on the other hand is an "8-bit integer", or a number that can be positive or negative (so the range is -128 to 127). The same basic idea applies to the *16 and *64 variants, just with 16 bits or 64 bits. A float represent a floating point number (a number with a fractional part, such as 1.2345), generally 4 bytes long. Additionally, you need to know the order to interpret the bytes within a word (left-to-right or right-to-left). This is referred to as the endianness, and every computer architecture has a native endianness (big-endian or little-endian).
Given all of that, you can interpret the PacketHeader. The easiest way is probably to use the struct package in Python. Details can be found here:
https://docs.python.org/3/library/struct.html
As a proof of concept, the following will interpret the first 24 bytes:
import struct
data = b'\xe4\x07\x01\x03\x01\x07O\x90.\xea\xc2!7\x16\xa5\xbb\x02C\xda\n\x00\x00\x00\xff\x01\x00\x03:\x00\x00\x00 A\x00\x00\xdcB\xb5+\xc1#\xc82\xcc\x10\t\x00\xd9\x00\x00\x00\x00\x00\x12\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$tJ\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
#Note that I am only taking the first 24 bytes. You must pass data that is
#the appropriate length to the unpack function. We don't know what everything
#else is until after we parse out the header
header = struct.unpack('<HBBBBQfIBB', data[:24])
print(header)
You basically want to read the first 24 bytes to get the header of the message. From there, you need to use the m_packetId field to determine what the rest of the message is. As an example, this particular packet has a packetId of 7, which is a "Car Status" packet. So you would look at the packing format for the struct CarStatus further down on that page to figure out how to interpret the rest of the message. Rinse and repeat as data arrives.
Update: In the format string, the < tells you to interpret the bytes as little-endian with no alignment (based on the fact that the documentation says it is little-endian and packed). I would recommend reading through the entire section on Format Characters in the documentation above to fully understand what all is happening regarding alignment, but in a nutshell it will try to align those bytes with their representation in memory, which may not match exactly the format you specify. In this case, HBBBBQ takes up 2 bytes more than you'd expect. This is because your computer will try to pack structs in memory so that they are word-aligned. Your computer architecture determines the word alignment (on a 64-bit computer, words are 64-bits, or 8 bytes, long). A Q takes a full word, so the packer will try to align everything before the Q to a word. However, HBBBB only requires 6 bytes; so, Python will, by default, pad an extra 2 bytes to make sure everything lines up. Using < at the front both ensures that the bytes will be interpreted in the correct order, and that it won't try to align the bytes.
Just for information if someone else is looking for this. In python there is the library f1-2019-telemetry existing. On the documentation, there is a missing part about the "how to use" so here is a snippet:
from f1_2020_telemetry.packets import *
...
udp_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
udp_socket.bind((host, port))
while True:
udp_packet = udp_socket.recv(2048)
packet = unpack_udp_packet(udp_packet)
if isinstance(packet, PacketSessionData_V1): # refer to doc for classes / attribute
print(packet.trackTemperature) # for example
if isinstance(packet, PacketParticipantsData_V1):
for i, participant in enumerate(packet.participants):
print(DriverIDs[participant.driverId]) # the library has some mapping for pilot name / track name / ...
Regards,
Nicolas

Concatenated SMS extended symbols at segments border - what is correct split method?

For concatenated SMS messages (in GSM encoding), if extended table symbol (one of these: }{[]|~^\€) is placed at the end of segment, what is correct way to split such message:
Leave first byte of symbol (0b) at the end of segment and put second byte to the beginning of next one, and so fill all available bytes of UD (which seems logically correct)
OR
Move whole symbol bytes to the next segment and leave unused byte at the end?
I didn't found any clarification neither in SMPP 3.4 specs or implementation guide nor in GSM 03.38 specs, so assume that method selection is up to content provider or sending software.
When you are using a 7-bit encoding, split when you reach 153 characters (whether that is in-between the 1B and the next character or not).
I can't think of any reason to prefer option 2 (leave unused byte at the end).
The message should not be rendered unless it's completely received by the subscriber's device. Furthermore, nothing is even represented by 1B septet in GSM7, so even if a device tried to render something unexpected it would fail.

using int64 type for snmp v2c oid?

I am debugging some snmp code for an integer overflow problem. Basically we use an integer to store disk/raid capacity in KB. However when a disk/raid of more than 2TB is used, it'll overflow.
I read from some internet forums that snmp v2c support integer64 or unsigned64. In my test it'll still just send the lower 32 bits even though I have set the type to integer64 or unsigned64.
Here is how I did it:
a standalone program will obtain the capacity and write the data to a file. example lines for raid capacity
my-sub-oid
Counter64
7813857280
/etc/snmp/snmpd.conf has a clause to pass thru the oids:
pass_persist mymiboid /path/to/snmpagent
in the mysnmpagent source, read the oidmap into oid/type/value structure from the file, and print to stdout.
printf("%s\n", it->first.c_str());
printf("%s\n", it->second.type.c_str());
printf("%s\n", it->second.value.c_str());
fflush(stdout);
use snmpget to get the sub-oid, and it returns:
mysuboid = Counter32: 3518889984
I use tcpdump and the last segment of the value portion is:
41 0500 d1be 0000
41 should be the tag, 05 should be the length, and the value is only carrying the lower 32-bit of the capacity. (note 7813857280 is 0x1.d1.be.00.00)
I do find that using string type would send correct value (in octetstring format). But I want to know if there is a way to use 64-bit integer in snmp v2c.
I am running NET-SNMP 5.4.2.1 though.
thanks a lot.
Update:
Found the following from snmpd.conf regarding pass (and probably also pass_persist) in net-snmp doc page. I guess it's forcing the Counter64 to Counter32.
Note:
The SMIv2 type counter64 and SNMPv2 noSuchObject exception are not supported.
You are supposed to use two Unsigned32 for lower and upper bytes of your large number.
Counter64 is not meant to be used for large numbers this way.
For reference : 17 Common MIB Design Errors (last one)
SNMP SMIv2 defines a new type Counter64,
https://www.rfc-editor.org/rfc/rfc2578#page-24
which is in fact unsigned 64 bit integer. So if your data fall into the range, using Counter64 is proper.
"In my test it'll still just send the lower 32 bits even though I have set the type to integer64 or unsigned64" sounds like a problem, but unless you show more details (like showing some code) on how you tested it out and received the result, nobody might help further.

Embedding GSM cellids in Short Messages

I'm using the WML function "providelocalinfo" to put location information into Short Messages send via a WIB menu on a GSM handset.
I'm using the WIG WML v.4 Spec from SmartTrust. The relevant section is "9.4 providelocalinfo Element"
I use the code as in the example, and then transmit the variable via SMS, and use Kannel to retrieve the message from the SMSC.
Here's the code that I'm using, with the exception of [myservicecentre] being my actual service centre:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE wml PUBLIC "-//SmartTrust//DTD WIG-WML 4.0//EN"
"http://www.smarttrust.com/DTD/WIG-WML4.0.dtd">
<wml wibletenc="UCS2">
<card id="s">
<p>
<providelocalinfo cmdqualifier="location" destvar="LOC"/>
<setvar name="X" value="loc=" class="binary"/>
<sendsm>
<destaddress value="367"/>
<userdata docudenc="hex-binary" dcs="245">
$(X)$(LOC)
</userdata>
<servicecentreaddress value="[myservicecentre]"/>
</sendsm>
</p>
</card>
</wml>
What I see in my received messages is "loc=" followed by 7 bytes (octets) or binary data. I have tried to find documentation explaining how to decode this data, but found nothing the explains this clearly.
Of the decoded 7 octets,
the first 3 octets are always the same,
The next 2 octets tend to vary between three unique values,
the last 2 octets appear to be the cellid.
So I have coded the receiver to pull the last two octets and construct a 16-bit GSM cellid. Most of the time it matches known cellids from the network. But quite often, the value does not match.
So I'm trying to find information on the following:
How to properly transmit the location information in a safe manner (encodings, casts, etc)
How to decode the information properly
How to configure Kannel to honor binary location data
I've examined the following documents in my vain searching, but not found the relevant data:
GSM 03.38, GSM 04.07, GSM 04.08, GSM 11.15, as well as the WIG WML Spec V .4
Any insight into what I might be doing wrong would be appreciated!
To decode the location info, you need to look in GSM 11.14 page 48
1.19 LOCATION INFORMATION
Byte(s) Description Length
1 Location Information tag 1
2 Length (X) of bytes following 1
3-5 Mobile Country & Network Codes (MCC & MNC) 3
6-7 Location Area Code (LAC) 2
8-9 Cell Identity Value (Cell ID) 2
The mobile country code (MCC), the mobile network code (MNC), the location area code (LAC) and the
cell ID are coded as in TS GSM 04.08 [8].
From personal experience, the first octet mentioned here is usually left off, so your first three unchanging bytes are the length and the country. The next 2 are the network operator code.
Not too many bites on this question! I wanted to summarize my findings in case others can find them useful:
Need to send messages with a dcs setting not equal to 0. dcs="0" sends data packed (honoring the lower 7-bits of each octet; this allows 160 character SMS messages when the max message size is actually 140 octets)
Need to parse the data in a binary safe manner: regex expressions that stop searching when 0x0A is encountered will fail when the binary data itself can be that value.
I found no need to change Kannel's default configuration.
Cheers
Disclaimer: Safe transmission of 16-bit GSM Cell-Ids requires dealing with a few settings that I understand only because they weren't configured by default. There are probably other defaults that I've depended on but am unaware that they can vary.

Resources