Rapid SCADA can display a Modbus register as text when the received value retains the correct byte order and the channel uses ASCII data with String format. For strings of eight bytes or fewer, start with channel configuration alone; add a calculated channel and custom script only when the text spans more data or needs assembly with numeric fields.
Raw Modbus Response Check
- Open the Communicator log and locate the request for the register carrying the text.
- Read the byte count and data bytes from the response. Do not infer the text from the displayed decimal channel value.
- Translate each data byte directly through the ASCII table. Do not move on until the wire bytes spell the expected characters in one identifiable order.
For example, one request read holding register with a quantity of one register:
Send (12): 00 39 00 00 00 06 01 03 00 36 00 01
Receive (7): 00 39 00 00 00 05 01
Receive (4): 03 02 53 4E
The function code is 03, the byte count is 02, and the data bytes are 53 4E. Direct ASCII interpretation produces SN. A channel may display the same two bytes as decimal 21326 because equals 21326; that decimal display does not mean that the device omitted the text.
Keep three representations separate during diagnosis: wire-byte sequence, numeric register value, and decoded character sequence. A hexadecimal number such as is an integer rendering, not a declaration that the wire delivered byte 4E before byte 53.
Direct Channel Configuration
- Configure the Communicator data item so the channel receives the value as
Double. - Set the input channel data type to
ASCII. - Set the channel format to
String. - Leave the input formula empty for an ASCII value of eight bytes or fewer.
- Refresh the table and confirm that the expected text appears before adding any calculation or script.
This is the shortest resolving branch for a single packed value no longer than eight ASCII characters. The working eight-character case required no formula: Communicator supplied Double, while the channel used ASCII and String.
Do not change the template value type to ulong merely because the payload represents unsigned bytes. Rapid SCADA carries numeric channel values through a double-based path, and extra conversions can alter how a formula reconstructs the integer before decoding. Leave the transport value as Double unless a tested custom script explicitly performs the conversion.
Byte-Order Decision
If direct configuration produces reversed character pairs, keep the channel settings and correct the byte permutation in the Communicator driver. Byte order belongs at the acquisition boundary when the driver provides a permutation control.
- Compare the logged bytes with the expected ASCII codes.
- If every adjacent character pair is reversed, change the driver byte permutation and acquire a fresh sample.
- If the entire string is reversed rather than each pair, inspect the register ordering as a separate issue.
- Confirm the corrected string in the channel table; do not validate the change from the decimal value alone.
In the two-byte SN case, the initially reported permutation 01 was corrected to 10. That setting is installation-specific: select the permutation by comparing the log bytes and decoded output, because drivers can label byte-order options differently.
An eight-byte example arrived as four words:
5432 4D50 2E31 5352
The intended result was 2TRM1.RS. A corrupted or missing leading 2 points first to representation or byte-order handling, not to a missing character at the device, because ASCII 2 is present as byte 32. Use the logged 32 byte as the anchor while selecting the permutation.
Formula Branch for Short Values
Use an input formula only after direct ASCII/String configuration and byte-order correction have been tested. The built-in short-value form is:
DecodeAscii(Cnl)
Cnl refers to the current input-channel value. Calling val() without a defined channel reference does not supply the packed register value. Data() is not the required argument for this conversion; that attempt caused the server to stop in the observed configuration.
When DecodeAscii(Cnl) still displays a number, check the channel metadata before changing the formula. The channel must use String format and the appropriate ASCII data type. A formula can return decoded text while the display layer still renders the channel as numeric when its format remains numeric.
Inspect the formula code for EncodeAscii and DecodeAscii in the Scripts table when behavior is unclear. Display the raw source channel in hexadecimal during commissioning so byte placement remains visible.
Numeric Reconstruction Mechanism
A Modbus register carries bytes, while the SCADA channel core represents acquired numeric values as double. Reading the in-memory bytes of that double does not reproduce the bytes of the original register. The conversion must first recover an integer with the same numeric value, then extract that integer's bytes and decode them as ASCII.
A custom short-value function demonstrated that sequence:
public string ToAscii(double val)
{
long ll = Convert.ToInt64(val);
byte[] buf = BitConverter.GetBytes(ll);
return Encoding.ASCII.GetString(buf).TrimEnd((char)0);
}
TrimEnd((char)0) removes trailing null padding. An unsigned variant can use Convert.ToUInt64(val), but switching signedness does not correct byte order. For the same underlying bit pattern, byte position remains the deciding factor.
ToAscii(Cnl) works only after ToAscii has been added as a custom script function. Calling an undefined custom function directly from a channel formula is not a configuration shortcut. Test custom functions in a calculated channel while leaving acquisition channels unchanged.
Long-String and Mixed-Field Branch
The built-in short conversion handles up to eight ASCII characters. Use separate raw input channels plus a calculated channel when the string exceeds eight ASCII characters, spans multiple independently read registers, or must be combined with numeric fields and punctuation.
- Acquire every source register into an unmodified input channel.
- Show the source channels in hexadecimal while commissioning.
- Add a calculated channel with
Stringformat. - Read consecutive source channels with
Val(firstChannel + offset). - Convert each value according to its packed length, concatenate the fragments, and publish only the calculated channel to operators.
The following function supports 2-, 4-, and 8-byte packed values:
public string GetRegAscii(int ftNum, int quant, int paramlen = 2)
{
string outStr = "";
List<string> lStr = new List<string>();
for (int i = 0; i < quant; i++)
{
var str = "";
if (paramlen == 2)
{
ushort us = Convert.ToUInt16(Val(ftNum + i));
byte[] buf = BitConverter.GetBytes(us);
str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
}
else if (paramlen == 4)
{
uint ui = Convert.ToUInt32(Val(ftNum + i));
byte[] buf = BitConverter.GetBytes(ui);
str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
}
else if (paramlen == 8)
{
ulong ul = Convert.ToUInt64(Val(ftNum + i));
byte[] buf = BitConverter.GetBytes(ul);
str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
}
lStr.Add(str);
}
if (lStr.Count > 0)
outStr = string.Join("", lStr.ToArray());
return outStr;
}
For a packed eight-byte value in channel 300, the example call is GetRegAscii(300, 1, 8): 300 is the first source channel, 1 is the number of channels to process, and 8 is the packed byte length. When registers are acquired separately as two-byte values, retain the default paramlen of 2 and set quant to the number of consecutive source channels.
If a downstream operation must distribute the returned text, the demonstrated wrapper form was SplitAscii(()=> GetRegAscii(300, 1, 8)). Use the wrapper only where that split behavior is required; a calculated string channel can call GetRegAscii(300, 1, 8) directly.
Symptom-to-Cause Checks
| Observed result | Reading to take | Likely cause | Next check |
|---|---|---|---|
Decimal 21326 instead of SN
|
Log shows 53 4E
|
Channel remains numerically formatted | Set ASCII and String
|
| Adjacent characters reversed | Compare each logged byte pair with ASCII codes | Word byte permutation | Change the Communicator permutation and reacquire |
| Seven of eight characters decode | Locate the missing character's byte in the log | Packed-length, conversion, or byte-order mismatch | Keep Double; verify all eight byte positions |
| Gray or non-string calculated value | Inspect calculated-channel format | Result is not identified for string display | Set calculated channel to String
|
| Long text is truncated | Count payload characters and source registers | Short conversion limit reached | Assemble consecutive raw channels with GetRegAscii
|
| Unexpected symbols | Compare raw bytes with the required character encoding | Wrong encoding or byte order | Confirm ASCII rather than Unicode, then retest permutation |
Commissioning and Final Verification
- Leave all device input channels formula-free and record their raw hexadecimal values.
- Confirm that every expected character exists in the Modbus response.
- For up to eight ASCII bytes, set Communicator acquisition to
Double, channel data type toASCII, and channel format toString. - If character pairs are reversed, correct the Communicator byte permutation and acquire a new value.
- If the value exceeds eight ASCII characters or combines mixed fields, create a calculated string channel and call
GetRegAsciiwith the verified first channel, channel count, and packed length. - Compare the displayed string character by character with the logged payload, including the first character, punctuation, register boundaries, and trailing-null removal.
FAQ
Can I display eight ASCII characters in Rapid SCADA without a formula?
Yes. Receive the value as Double, set the channel data type to ASCII, and set its format to String. Correct byte permutation in the Communicator if character pairs appear reversed.
Does DecodeAscii accept the current channel value?
Use DecodeAscii(Cnl) for the current input channel. Keep the channel formatted as String, and avoid substituting Data() or an undefined custom function.
Can I decode ASCII text longer than eight characters?
Yes. Preserve the registers in formula-free input channels, assemble them in a calculated string channel with a function such as GetRegAscii, then verify every character against the hexadecimal Communicator response.