- #!/bin/bash
- #logPath 写日志的存放路径
- #logPath=/home/workspace/tvs/trainborne
- logPath=/home/firefly
- tmpFile=$$
- function getLogName()
- {
- #echo "$logPath/LCDController_"`date +"%Y%m%d000000.log"`
- echo "LCDController_20240424000000.log"
- }
- # 串口设备文件
- SERIAL_PORT="/dev/ttyS0"
-
- # 设置串口参数
- stty -F $SERIAL_PORT 9600 cs8 -cstopb -parenb
-
- # 要发送的16进制数据,这里以 "48 65 6c 6c 6f"(即 "Hello" 的ASCII码)为例
- OPEN_HEX_DATA="aa aa 80 01 00 00 00 03 00 00 00 08 ff ff 06 01 00 18 02 1d db d3 07 58"
- CLOSE_HEX_DATA="aa aa 80 01 00 00 00 03 00 00 00 08 ff ff 06 01 00 18 01 1E 69 f7 05 21"
-
- # 使用printf发送16进制数据,注意前面加上了'\x'来指定是16进制
- # 这里使用了一个循环来遍历HEX_DATA中的每个值
- closeScreen()
- {
- # echo `date +"%Y-%m-%d %H:%M:%S"`" closeScreen" >>tmp.log
- echo `date +"%Y-%m-%d %H:%M:%S"`" closeScreen"
- OLD_IFS=$IFS
- IFS=' ' # 设置内部字段分隔符为空格
- read -ra ADDR <<< "$CLOSE_HEX_DATA" # 将HEX_DATA分割为一个数组
- IFS=$OLD_IFS # 恢复原始的内部字段分隔符
-
- for byte in "${ADDR[@]}"; do
- printf "\\x$byte" > $SERIAL_PORT
- done
- }
- openScreen()
- {
- echo `date +"%Y-%m-%d %H:%M:%S"`" openScreen" >>tmp.log
- echo `date +"%Y-%m-%d %H:%M:%S"`" openScreen"
- OLD_IFS=$IFS
- IFS=' ' # 设置内部字段分隔符为空格
- read -ra ADDR <<< "$OPEN_HEX_DATA" # 将HEX_DATA分割为一个数组
- IFS=$OLD_IFS # 恢复原始的内部字段分隔符
-
- for byte in "${ADDR[@]}"; do
- printf "\\x$byte" > $SERIAL_PORT
- done
- }
- function Test()
- {
- closeScreen
- sleep 2
- openScreen
- exit 0
- }
- echo "执行$0 test 可以测试串口开关屏"
- if [ "$1" == "test" ]; then
- echo "call test"
- Test
- exit 0
- fi
- # 如果你知道发送的数据量并且想要一次发送所有字节(注意:这可能在某些shell中不起作用)
- # echo -ne '\x48\x65\x6c\x6c\x6f' > $SERIAL_PORT
- # 注意:上面的-ne选项在bash中是有效的,但在某些shell中可能不支持
-
- # 读取并显示来自串口的响应(如果需要的话)
- # cat $SERIAL_PORT
- log=$(getLogName)
- grep -rn "trun on" $log |awk '{print $1}'> $tmpFile
- i=0
- while read -r value;
- do
- strArray["$i"]="$value"
- i=$((i+1))
- done < $tmpFile
- rm $tmpFile
- i=$((i-1))
- if [ $i -ne "-1" ]; then
- tmp=${strArray[$i]}
- tmp=`echo $tmp|cut -d':' -f1`
- i=$((tmp+8))
- tmp=`sed -n "$i"p $log`
- tmpDate=`echo $tmp|cut -d'.' -f1`
- timeStampTmp=`date -d "$tmpDate" +%s`
- now=`date`
- timeStampNow=`date -d "$now" +%s`
- diff=$((timeStampNow-timeStampTmp))
- if [ $diff -lt 60 ]; then
- echo `date +"%Y-%m-%d %H:%M:%S"`" grep string $tmp" >tmp.log
- echo `date +"%Y-%m-%d %H:%M:%S"`" grep string $tmp"
- tmp=`echo $tmp|cut -d':' -f6`
- if [ $tmp == 31 ]; then
- echo "open screen" >> tmp.log
- openScreen
- else
- echo "close screen" >> tmp.log
- closeScreen
- fi
- fi
- fi
- exit 0
函数返回字符串可以用echo 来实现
使用时log=$(getLogName),一定要用$()才可以,不然getLogName就会被当成字符串
但是这样调用函数时,函数内不能正常使用echo 打印调试内容。
shell 可以直接操作串口,使用stty 设置串口参数
echo `date +"%Y-%m-%d %H:%M:%S"`" closeScreen"
日期格式输出date +"%Y-%m-%d %H:%M:%S
OLD_IFS=$IFS
IFS=' ' # 设置内部字段分隔符为空格
read -ra ADDR <<< "$CLOSE_HEX_DATA" # 将一串包含空格的数据分割为一个数组保存
IFS=$OLD_IFS # 恢复原始的内部字段分隔符
for byte in "${ADDR[@]}"; do
printf "\\x$byte" > $SERIAL_PORT
done
使用printf发送16进制数据,注意前面加上了'\x'来指定是16进制,例要发16进制AB到串口,就要发字符串\xAB,\x又要用\\x来表示,所以是'\\xAB'
把awk的结果定到文件,再读取文件数据内容保存到数组中
while read -r value;
do
strArray["$i"]="$value"
i=$((i+1))
done < $tmpFile
$(())可以用来直接进行数学运算,变量在里面直接用
访问数组元素tmp=${strArray[$i]}
单独显示文件特定行内容
tmp=`sed -n "$i"p $log`
把时间的字符串换算成跟1970年的时间的秒数,方便进行比较时间差
timeStampTmp=`date -d "$tmpDate" +%s`