Appeared customer display. It became interesting to try to use it as an information board for displaying information about the current day, time until the end of the working day / week, weather information, and exchange rates.
At the same time, I did not want to use resource-intensive applications and my PC. I stopped at a bunch of mini-PC Raspberry + Linux + Customer Display.
I don’t consider installing and configuring Linux on a Raspberry device in this article.
To edit text in the Linux environment, I used nano and mcedit editors.
To access a mini-PC based on Linux OS from a Windows environment, I used clients for remote access via the SSH protocol - KiTTY / PuTTY.
To transfer files between Windows and Linux, I used WinSCP.
Bash - command interpreter (command shell).
Bash is an abbreviation of "Bourne-Again Shell" ("revived" shell). Keywords, syntax, and other basic features of the language were borrowed from another sh command interpreter (short for shell).
Bash is also a powerful programming language.
')
I am engaged in maintenance of software products based on 1C and for me it was an opportunity to get acquainted with programming in the Linux environment.
To the best of my understanding, I will explain the commands being executed. This is done for the purpose of a large audience.
After you have attached a customer display (PD) to the USB port, find out the parameters of the connected device. In the terminal, execute the command:
usb-devices
Get the list of attached USB devices to the Raspberry:
T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0002 Rev=04.14 S: Manufacturer=Linux 4.14.69-v7+ dwc_otg_hcd S: Product=DWC OTG Controller S: SerialNumber=3f980000.usb C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 5 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1 P: Vendor=0424 ProdID=9514 Rev=02.00 C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=2mA I: If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0424 ProdID=ec00 Rev=02.00 C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=2mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=ff Driver=smsc95xx T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0131 Rev=01.00 S: Manufacturer=www.posua.com S: Product=POSua LPOS-II-VFD USB CDC C: #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=16mA I: If#= 0 Alt= 0 #EPs= 3 Cls=02(commc) Sub=02 Prot=01 Driver=usbserial_generic I: If#= 1 Alt= 0 #EPs= 2 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid
From the information received by the command, we find the line Product = POSua LPOS-II-VFD USB CDC . This is our customer display. In this section, we need the string Vendor = 0000 ProdID = 0131 Rev = 01.00. And specifically vendor = 0000 prodID = 0131 . This is how the device identifies itself.
For correct work with DP, it is necessary to load the work module from USB into the system core. We execute the command with elevated rights:
sudo modprobe usbserial vendor=0x0000 product=0x0131
modprobe
is a program for adding modules to the Linux kernel. usbserial
is a kernel module that emulates a COM port on USB devices. 0x is a hexadecimal format.
Since I have one USB device connected, the Linux system automatically receives the ttyUSB0 file. This is an important feature of interaction with devices in Linux OS - working with the device as a file. Device files are stored in the /dev
.
To work correctly with DP, set the data transfer rate:
stty -F /dev/ttyUSB0 9600
stty
- the command sets the terminal input / output parameters for the device. -F
- device. In our case, the customer display is /dev/ttyUSB0
. And for this device is set to 9600 baud.
Now you can try to display a welcome message (while in English):
echo "Hello!" > /dev/ttyUSB0
If everything is done correctly, then our message will appear on the screen. Read more about the team below.
In the previous step, we displayed a message in English on top of the device’s splash message. And it is not very beautiful.
To clear the display screen, execute the command:
echo -e -n "\x0c\x0b" > /dev/ttyUSB0
echo
- command output to the terminal. The option -e
- includes support for outputting escape sequences, -n
- indicates that it is not necessary to print a line break. A -en
entry is allowed.
A combination of characters consisting of a backslash \
followed by a letter or a set of numbers is called escape sequences.
0
- clears the display screen and cancels line mode, 0b
- moves the cursor to the upper leftmost position. Symbol >
- flow control (redirects output). In this case, in the / dev / ttyUSB0 file of our device. If you just run the echo "Hello!"
command echo "Hello!"
then the text in quotes will appear in the terminal window.
By the way, the command changing the speed for transferring data to the device could be written like this:
stty 9600 < /dev/ttyUSB0
Well, to display messages in Russian, let's execute:
echo -n "!" | iconv -f UTF-8 -t CP866 > /dev/ttyUSB0
|
- redirects the output of one command to the input of another (pipeline). In our case, the sequence of characters "Hello!" It is not displayed in the device file immediately, but is transferred to the "convert" utility iconv. iconv
- converts from one encoding to another.
The bash command interpreter allows you not only to execute commands directly in the terminal, but also to write script files.
A script is a plain text file with a sequence of commands executed.
In order for bash to understand that this "it" at the beginning of the file is indicated #! / Bin / bash . To execute the script directly, execute the command:
sudo chmod u+x namefile.sh
Where namefile.sh is a script file. The sh extension means that it is a bash script file. chmod
is a program for changing permissions of files and directories. u+x
- sets the right to execute the file for the current user.
The solution of the problem will be executed by two scripts. The first script is the main ( dispos.sh ). It displays all the necessary information on the display of the buyer. The second - auxiliary ( parse.sh ) receives weather data, currency quotation services and writes data to intermediate files. Intermediate data files are used in the first script.
In order for scripts to run, you need to run the following commands:
sudo chmod +x dispos.sh sudo chmod +x parse.sh
Note that it uses just +x
. This is the shortened version of u+x
.
Scripts must be run at regular intervals. To do this, we use the standard crontab scheduler. To edit the command:
crontab -e
Add two lines to the scheduler:
*/20 * * * * /home/pi/parse.sh */1 * * * * /home/pi/dispos.sh
The parse.sh script runs every 20 minutes, and the dispos.sh script runs every minute.
Before the initial output to the customer’s display, one must first execute the parse.sh script which will receive the primary weather and currency data.
./parse.sh
Further I will give the full texts of scripts with short comments.
#!/bin/bash # POSua LPOS-VFD. # - ttyUSB0. # tty : # modprobe usbserial vendor=0x0000 product=0x0131. # 0x0000 0x0131 , # usb-devices, lsusb dmesg. # stty 9600 < /dev/ttyUSB0. # parse.sh # crontab . # **************************************************************** # # ttyUSB - (POS-) DEV_DISPLAY="/dev/ttyUSB0" # # , , 18:00:00 # 17:00:00 TIME_OF_WORKDAY="18:00:00" if (( $(date "+%u") >= 5 )); then TIME_OF_WORKDAY="17:00:00" fi # ( 17:00:00) # DAY_OF_WEEKEND=`date +"%s" --date="friday 17:00:00"` # **************************************************************** # # disp_clear(){ echo -en "\x0c\x0b" > "${DEV_DISPLAY}" } # disp_cr(){ echo -e "\x0b" > "${DEV_DISPLAY}" } # disp_print(){ echo -n $1 | iconv -f UTF-8 -t CP866 > "${DEV_DISPLAY}" } # **************************************************************** # # 1. disp_clear # disp_print ": `date "+%A"`" disp_cr # disp_print " `date "+%d.%m.%Y %H:%M"`" sleep 8 # **************************************************************** # 2. disp_clear disp_print " . :" disp_cr HOURS=$(( ( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) / 3600 )) MINUTES=$(( (( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) - $HOURS * 3600) / 60 )) # if (( $MINUTES > -1 )); then OUTPUT_TIME=" ${HOURS} . ${MINUTES} ." else OUTPUT_TIME=" !" fi # disp_print "${OUTPUT_TIME}" sleep 8 # **************************************************************** # 3. disp_clear disp_print " . :" disp_cr DAYS=$(( ($DAY_OF_WEEKEND-$(date +%s)) / (24*3600) )) HOURS=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600)) / 3600 )) MINUTES=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600) - ($HOURS*60*60)) / 60 )) # if (( $MINUTES > -1 )); then OUTPUT_TIME="${DAYS} . ${HOURS} . ${MINUTES} " else OUTPUT_TIME=" !" fi # disp_print "${OUTPUT_TIME}" sleep 8 # **************************************************************** # 4. # 4.1. LINE1=$(sed -n '1{p;q}' /tmp/weather.txt) DISPLAY_LINE1=${LINE1:0:19} DISPLAY_LINE2=${LINE1:19:19} # (2 ) disp_clear disp_print "${DISPLAY_LINE1}" disp_cr disp_print "${DISPLAY_LINE2}" sleep 4 # 4.2. LINE1=$(sed -n '2{p;q}' /tmp/weather.txt) DISPLAY_LINE1=${LINE1:0:14} DISPLAY_LINE2=${LINE1:14:19} # (2 ) disp_clear disp_print " ${DISPLAY_LINE1}" disp_cr disp_print "${DISPLAY_LINE2}" sleep 8 # **************************************************************** # 5. # # DOLLAR=$(sed -n '1{p;q}' /tmp/ex.txt) DOLLAR=${DOLLAR//–/-} # EURO=$(sed -n '2{p;q}' /tmp/ex.txt) EURO=${EURO//–/-} # disp_clear disp_print ": ${DOLLAR}" disp_cr disp_print ": ${EURO}" sleep 8 # **************************************************************** # 6. # # BTC while read line do BTC=${line:0:13} done </tmp/bitcoin.txt # ETH while read line do ETH=${line:0:13} done </tmp/ethereum.txt # # disp_clear disp_print "BTC: ${BTC//./,}" disp_cr disp_print "ETH: ${ETH//./,}" #sleep 8 # **************************************************************** # 7. # (. 20 ) #DISPLAY_LINE1=" !" #DISPLAY_LINE2=" !" # #disp_clear #disp_print "${DISPLAY_LINE1:0:19}" #disp_cr #disp_print "${DISPLAY_LINE2:0:19}"
Comments
To display the current date, use the date
command. Example,
echo `date "+%d.%m.%Y %H:%M"`
After the execution, we get the date of the form: 05/20/2019 12:11.
To calculate the time until the end of the day, we use the additional variable TIME_OF_WORKDAY
and set the value TIME_OF_WORKDAY="18:00:00"
. Well, then we calculate the hours and minutes until the end of the working day:
HOURS=$(( ( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) / 3600 )) MINUTES=$(( (( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) - $HOURS * 3600) / 60 ))
The $
symbol indicates that this is a variable.
The #
symbol is a comment.
date +%s
- we get the current date and time in seconds.date +%s --date=$TIME_OF_WORKDAY
- we get the time in seconds to TIME_OF_WORKDAY ("18:00:00")
.
Calculate the time until the end of the work week:
DAYS=$(( ($DAY_OF_WEEKEND-$(date +%s)) / (24*3600) )) HOURS=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600)) / 3600 )) MINUTES=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600) - ($HOURS*60*60)) / 60 ))
Where DAY_OF_WEEKEND=`date +"%s" --date="friday 17:00:00"`
is the time in seconds from the current time to Friday 17:00:00.
Part of the script is implemented using functions. For example,
# disp_clear(){ echo -en "\x0c\x0b" > "${DEV_DISPLAY}" }
disp_clear()
is the name of the function. {}
Specifies the commands to be executed.
The variable DEV_DISPLAY
is "global" and is specified at the beginning of the script and accordingly DEV_DISPLAY="/dev/ttyUSB0"
.
Reading data from a file, for example a specific line (1):
LINE1=$(sed -n '1{p;q}' /tmp/weather.txt)
sed
is a text editor that performs editing operations on information in a standard input stream or file. The -n
displays the current selected line. '1{p;q}'
- prints 1 line and leaves without reading the rest ( p
- print, q
- exit).
Another option to read from the file (line by line):
while read line do BTC=${line:0:13} done </tmp/bitcoin.txt
And thus DISPLAY_LINE1=${LINE1:0:14}
from the line LINE1
extract a substring 14 characters long starting from 0.
Replacing characters is done by a //
combination, for example, DOLLAR//–/-
. Replaced the symbol "-" by "-".
#!/bin/bash # RSS http://rp5.ru/rss/1859/ru # 1859 - # conv(){ # CURRENCY=$(sed -n '1!G;h;$p' /tmp/ex.xml | sed -n "${1}{p;q}") CURRENCY=${CURRENCY//[^,^(^)^0-9^–^+]/} echo $CURRENCY } # c # 1. wget -q -O /tmp/rp5weather.xml http://rp5.ru/rss/1859/ru # 2. wget -q -O /tmp/ex.xml http://currr.ru/rss/ # 3. bitcoin/ethereum wget -q -O /tmp/bitcoin.json https://api.coinmarketcap.com/v1/ticker/bitcoin/ wget -q -O /tmp/ethereum.json https://api.coinmarketcap.com/v1/ticker/ethereum/ # # , , # LINE31=$(sed -n '31{p;q}' /tmp/rp5weather.xml) LINE33=$(sed -n '33{p;q}' /tmp/rp5weather.xml) WEATHER1=${LINE31//"</title>"} WEATHER1=${WEATHER1//" °C"} WEATHER1=${WEATHER1//" "} WEATHER1=${WEATHER1:29} WEATHER2=${LINE33##*} WEATHER2=${WEATHER2//"°"} echo "${WEATHER1}" > /tmp/weather.txt echo ${WEATHER2%.*} >> /tmp/weather.txt # Bitcoin LINEBTC=$(sed -n '7{p;q}' /tmp/bitcoin.json) echo "${LINEBTC//[^.^0-9]/}" > /tmp/bitcoin.txt # Ethereum LINEETH=$(sed -n '7{p;q}' /tmp/ethereum.json) echo "${LINEETH//[^.^0-9]/}" > /tmp/ethereum.txt # DOLLAR=$(conv 8) echo $DOLLAR > /tmp/ex.txt EURO=$(conv 6) echo $EURO >> /tmp/ex.txt
Comments
The wget
command allows you to download files, pages, etc. from the network. Option -q
- displays a minimum of information, -O
- saves to the specified file.
The lines below are written to the file:
echo "${WEATHER1}" > /tmp/weather.txt echo ${WEATHER2%.*} >> /tmp/weather.txt
Moreover, if the output stream is redirected to the file >
, then the contents of the file are overwritten, and the use >>
adds data to the file.
An example of using a parameter in a function:
conv 6
Directly in function:
CURRENCY=$(sed -n '1!G;h;$p' /tmp/ex.xml | sed -n "${1}{p;q}")
Where {1}
is a parameter. The number 6 is transmitted.
Pay attention to the complicated function of substring substitution, for example:
LINEBTC//[^.^0-9]/
Only the "." and all numbers from 0 to 9.
Afterword
In the bash language, almost all features of "ordinary" programming languages are available. And some teams, compared to their counterparts in 1C, are surprised by their brevity and functionality.
At the moment, the customer display as an information board stably works for more than six months.
Source: https://habr.com/ru/post/457352/
All Articles