FOR TIPS, gUIDES & TUTORIALS

subscribe to our Youtube

GO TO YOUTUBE

14455 questions

17168 answers

28195 comments

0 members

We are migrating to our new platform at https://community.teltonika.lt. Moving forward, you can continue discussions on this new platform. This current platform will be temporarily maintained for reference purposes.
0 votes
476 views 4 comments
by anonymous

What is the best way to write binary values into /tmp/regfile to make them readable via custom modbus block ?

The couple of prototypes I have seen in these wiki pages seem pretty gross
The docs basically dance around the whole matter of the format required in the /tmp/regfile
I want to write binary 32bit INT and UINTs
Allegedly some of this could be done with printf ?
I assume that in order to have 32bit INT and UINTs appear in modbus registers, then those binary values need to be written into the file - unless there is some magic translation service which will convert from ascii to binary

I don't want to have to screw around re-assembling numbers from ASCII strings pulled across into the web portal
I found these shell-ready C functions which look like they will do the job...

1

A couple of more general functions to output integers to a file:

le16 () { # little endian 16 bit;  1st param: integer to 2nd param: file 
  v=`awk -v n=$1 'BEGIN{printf "%04X", n;}'`
  echo -n -e "\\x${v:2:2}\\x${v:0:2}" >> $2
}

le32 () { # 32 bit version
  v=`awk -v n=$1 'BEGIN{printf "%08X", n;}'`
  echo -n -e "\\x${v:6:2}\\x${v:4:2}\\x${v:2:2}\\x${v:0:2}" >> $2
}

I used to bash *ix bash , but have forgotten how primitive non-bash non-csh shells are.

It should be an unforgiveable offense for a shell to fail to implement $! to access the last argument of the last command ;-)
It appears to be working, but I cant tell for sure until I can test the modbus transfer
which seems to be buggered over this remote connection through RMS

1 Answer

0 votes
by anonymous

Hello,

Thank you for reaching out!

While I won't be able to provide a better solution than our Wiki, I could recommend a few solutions that might make it simpler:

  • Installing bash
    • Bash can be installed using opkg. Please keep in mind, that it will use around 15-17% of the flash storage, however, it can be expanded using an SD card or external flash drive;
    • Another solution to the storage could be to compile your own software using our SDK. Unnecessary packages can be removed, and bash can be added.
  • I don't want to have to screw around re-assembling numbers from ASCII strings pulled across into the web portal
    • This post seems to include a few solutions for converting ASCII to Binary using bash.

Hopefully these solutions will help.

Best regards,
DaumantasG

by anonymous

Thank you for your suggestion re bash... It is good to know that it is possible to build
custom applications...  I don't consider that effort to be worthwhile for this platform on which
I do not intend to spend any ongoing time - just enough to bolt a workable system together

I have started monkeying around with writing values into /tmp/regfile
I don't quite understand the nuances of this mechanism
The wiki shows an example of dumping a date in ASCII format into the /tmp/regfile.
That makes zero sense to me at all since reconstructing the date from a bunch of
ASCII fragments would be onerous/clunky
If I just ignore that and use the binary tools to write simple values into the file and then read them in the modbus master "window" I get values which do not match what I write...

Does anyone know what  word-order / byte order is required to write values recognized as 32bit ints 

- so I can converge more quickly than testing all the permutations:

1,2,3,4       3,4,1,2    4,3,2,1     2,1,4,3 ?

I plan to just prepare 3 variants of the le32 code above to test them all
I have already optimized the above code  by making $1 the output file and then arguments $2, $3, $4... the values to write
I noticed that when I write the value 1, I get a large 8 digit value...
It just occurred to me that could occur if the one-bit is written 1,2,3,4 when the system is expecting 4,3,2,1

Aha... I just worked it out in excel...  writing a single bit will be 256^0, 256^1, 256^2, 256^3 depending on the variant
that is 1, 256, 65536, and 16777216 - which I recognize from my testing

le16 () { # big endian 16 bit;  1st param: integer to 2nd param: file 
  v=`awk -v n=$2 'BEGIN{printf "%04X", n;}'`
  echo -n -e "\\x${v:0:2}\\x${v:2:2}" >> $1
}

be32 () { # 32 bit version of big-endian
  v=`awk -v n=$1 'BEGIN{printf "%08X", n;}'`
  echo -n -e "\\x${v:0:2}\\x${v:2:2}\\x${v:4:2}\\x${v:6:2}" >> $2
}
by anonymous

Hello,

  • That makes zero sense to me at all since reconstructing the date from a bunch of ASCII fragments would be onerous/clunky
    • Command date returns the date in ASCII format:
    • Thus no conversion to binary or hex is needed and ASCII data can be sent.
As I understand the issue with little endian and big endian is solved, correct?

 

It seems like you have an interesting project on your hands, so if you ever have some free time, it would be great if You could include a short summary here in case some clients ever face a similar issue. Thank you!

 

Best regards,
DaumantasG
by anonymous
Hello DaumantasG

The essence of one of the current projects is to use a digital input of the RUT955 to capture the pulse signal from a flowmeter.
Silly people sometimes cheap out when ordering equipment which is often communications-impaired in its default model.
In our case the flowmeters emit a pulse for a given quantity of water.
By incrementing a counter one can keep track of flow total.
By measuring the frequency on can measure the flow rate.
One way to obtain frequency is by measuring the period of the pulse train and invert that to calculate frequency.
This is just on the verge of being handle-able using shell-scripting - which avoids the song and dance of figuring out
how to use the SDK and programming environment and possibly not having direct or interrupt-driven access to the ioman.

The quick summary is to use shell-scripts using /tmp/files to store data and act as inter-process communications since I do not believe that this sandbox supports named pipes or other fancy stuff - which might also involve complexity to setup properly..
The calculated values are then written to /tmp/regfile which makes them available to Modbus SLave
From there they are pushed to the server...
all of the gory details are here:
https://community.teltonika-networks.com/57404/iojuggler-measure-period-frequency-digital-general-iojuggler?show=57404#q57404
by anonymous
Thank you!

Best regards,
DaumantasG