직렬 포트에 연결하고, 명령을 실행하고, 결과를 읽고, 결과를 캡처하고 종료합니다.

직렬 포트에 연결하고, 명령을 실행하고, 결과를 읽고, 결과를 캡처하고 종료합니다.

직렬 포트에 연결된 일부 장치가 있습니다. 실제로는 Arduino온도 센서를 기반으로 합니다.

나는 직렬 포트에 연결하고, 장치에 명령을 보내고, 응답을 받고, 인쇄 stdout하고 종료하는 스크립트를 작성하고 싶습니다.

이를 수행하는 올바른 방법은 무엇입니까?

일반적으로 로컬 프로그램에 액세스할 때 해당 출력을 리디렉션하는 것으로 충분합니다. 예를 들어, CPU온도를 읽는 방법은 다음과 같습니다.

datetime=$(date +%Y%m%d%H%M%S)
cputemp=$(sensors atk0110-acpi-0 | sed "s/CPU Temperature:[^0-9]*\([0-9\.]\+\).*/\1/;tx;d;:x")
echo "$datetime\t$cputemp"

불행하게도 $()직렬 통신에서는 그렇지 않은 명시적인 프로그램 종료에 의존합니다. 직렬 서버는 항상 온라인 상태이며 명시적인 "세션"이 없습니다.

물론 개행 문자를 확인할 수 있습니다. 하지만 이것이 옳은 일일까요? 모든 응답 이후에 전송 Arduino되도록 프로그램을 작성해야 할까요 Ctrl-Z?

답변1

말씀하신 대로 직렬 포트에서는 파일 끝을 읽을 수 없습니다. (Ctrl-Z는 Microsoft의 것입니다). 따라서 일반적으로 필요한 문자 수를 얻을 때까지 또는 구분 기호(예: 데이터 끝을 나타내는 개행 문자)를 찾을 때까지 읽습니다.

예를 들어 출력이 입력에 다시 연결되는 USB 직렬 포트가 있으므로 장치에 대한 모든 쓰기가 직접 반환됩니다. 다음 스크립트는 장치에서 보낸 콘텐츠를 검색할 수 있습니다.

#!/bin/bash
tty=/dev/ttyUSB0
exec 4<$tty 5>$tty
stty -F $tty 9600 -echo
echo abcdef >&5
read reply <&4
echo "reply is $reply"

스크립트는 직렬 장치를 입력용 파일 설명자 4, 출력용 파일 설명자 5로 연결하고 속도를 설정하고 tty가 가져오는 에코를 중지한 다음 장치에 "abcdef"와 개행 문자를 씁니다. 각 문자는 즉시 다시 전송되지만 커널 드라이버는 일부 입력을 버퍼링하므로 쓰기 전에 장치에서 읽기를 시작할 필요가 없습니다. 기본적으로 개행 문자가 보이면 읽기가 종료되며, 이를 변수에 저장한 reply다음 표준 출력에 표시합니다. 이 스크립트를 v=$()유형 사용에 넣을 수 있습니다 .

직렬 장치 데이터가 개행 문자로 끝나지 않는 경우 를 사용하여 bash 읽기에 다른 구분 기호를 지정할 수 있습니다 -d. 또는 응답 길이가 일정한 경우 지정된 길이를 사용할 수 있습니다 -n. 이진 데이터가 있는 경우 rawstty 명령에 추가하여 입력의 특수 처리를 중지해야 합니다.

관련 정보