250밀리초마다 데이터를 출력하는 직렬 장치(속도 레이더)가 있습니다.
이것이 내가 장치에 가지고 있는 것입니다:
1. Speed Packet Protocol
The Radar message packet consists of 7 bytes @ 1200 baud, no parity, 8 data bits, 1 start
bit. Messages are paced at 250mS intervals and are sent whether there is a target or not.
Char Description
1 <STX> Start of message
2 Status Radar status, as defined below
3 Patrol Speeds in binary from 4 to 255, Speed values below 4 are treated as
zero.
4 Target
5 Lock
6 Alt Alternate speed, as defined below
7 <ETX> End of message
1.1. Radar status byte
Bit Description/function if set
0 Low voltage error
1 Radio frequency interference error
2 Front antenna
3 Rear antenna
4 Moving mode
5 Alternate mode (fastest or slow)
6 Opposite direction mode
7 Always set (Indicated a speed packet)
Neither antenna being selected indicates standby.
Both antennae selected indicates a self-test is in progress. Test results are not sent, the
radar either returns to normal operation if successful or ceases communication in the
event of failure.
1.2. Alternate Speed
If the alternate mode bit is set, the alternate speed should be displayed. This will be
fastest if in opposite direction or slow if in same direction.
1.3. Message Receipt
Each message received should be time stamped and removed after 1 second if it has not
been replaced by a new message. The only exception is the self-test message, which
allows 8 seconds for the test to complete.
1.4. Example
Received sequence 02, 244(0xf4), 50, 99, 75, 01, 03.
Front antenna, moving mode, fastest mode, opposite direction mode, patrol speed of 50,
strongest target at 99, a locked speed of 75 and a no fastest target (since the value is
less that 4).
사용:
minicom -b 1200 -D /dev/ttyUSB0 -8 -H -w
0을 읽으면 데이터는 다음과 같습니다.
02 c8 00 00 00 00 03
다른 내용을 읽는 경우:
02 c8 00 16 00 00 03
또는
02 c8 00 0f 00 00 03
따라서 다음과 같이 보일 수 있습니다.
//How do I pipe the stream into the script??
"Get String Code Here"
//example string
$string=02 c8 00 16 00 00 03
//remove first part
$prefix=02 c8 00
//remove last part
$suffix=00 00 03
//result which appears to be a hex value
$result=16 (22MPH)
//convert $result to decimal
echo $result to monitor/file/database
나는 또한 더 잘 작동했으면 하는 C 스크립트를 발견했습니다.
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
//Initialize serial port
int initport(int fd)
{
int portstatus = 0;
struct termios options;
// Get the current options for the port...
tcgetattr(fd, &options);
// Set the baud rates to 115200...
cfsetispeed(&options, B1200);
cfsetospeed(&options, B1200);
// Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//options.c_cflag |= SerialDataBitsInterp(8); /* CS8 - Selects 8 data bits */
options.c_cflag &= ~CRTSCTS; // disable hardware flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable XON XOFF (for transmit and receive)
//options.c_cflag |= CRTSCTS; /* enable hardware flow control */
options.c_cc[VMIN] = 0; //min carachters to be read
options.c_cc[VTIME] = 0; //Time to wait for data (tenths of seconds)
// Set the new options for the port...
//tcsetattr(fd, TCSANOW, &options);
//Set the new options for the port...
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &options)==-1)
{
perror("On tcsetattr:");
portstatus = -1;
}
else
portstatus = 1;
return portstatus;
}
/*
* 'open_port()' - Open serial port 1.
*
* Returns the file descriptor on success or -1 on error.
*/
int open_port(void)
{
int fd; /* File descriptor for the port */
fd = open("/dev/ttyUSB0", O_RDONLY | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/*
* Could not open the port.
*/
perror("open_port: Unable to open /dev/ttyUSB0 --- \n");
}
else
fcntl(fd, F_SETFL, 0);
return (fd);
}
int main(void)
{
int serial_fd = open_port();
if(serial_fd == -1)
printf("Error opening serial port /dev/ttyUSB0 \n");
else
{
printf("Serial Port /dev/ttyUSB0 is now open \n");
// READ PORT DATA
if(initport(serial_fd) == -1)
{
printf("Error Initializing port");
close(serial_fd);
return 0;
}
sleep(.5);
//usleep(500000);
//printf("size of data being sent = %ld", sizeof("~ver~\n\r"));
sleep(.5);
//usleep(500000);
printf("\n\nNow closing Serial Port /dev/ttyUSB0 \n\n");
close(serial_fd);
}
return 0;
}
답변1
내 생각에 당신에게 필요한 것은 다음과 같습니다.
"Get String Code Here"
string="02 c8 00 16 00 00 03"
result=$(echo ${string} | cut -w -f 3)
그러나 이는 16진수이므로 비교가 까다로워집니다.
decimalresult=$(printf "%d" 0x${result})
물론 이 작업을 한 줄로 수행할 수도 있지만 명확성을 위해 이 방법으로 수행하겠습니다.
수정된 버전
스크립트의 일부로 읽어야 하는 연속 스트림이 있다고 하셨습니다. 쉘 스크립트는 일반적으로 한 줄씩 읽으므로 다음과 같이 합니다.
minicom
해당 출력을 사용하여 스크립트로 파이프 할 수 있습니다 .-H
쉘 스크립트는 바이너리 파일을 잘 처리하지 못하므로 16진수 출력을 얻으려면 이 옵션을 사용하십시오 . 이와 같이:
minicom -b 1200 -D /dev/ttyUSB0 -8 -H -w | this_script
- 입력은 파이프로 연결되고
dd
메시지를 구성하는 덩어리로 분할되며 끝에 줄 바꿈이 추가됩니다. - 이렇게 하면 한 줄에 7개의 항목을 읽고 네 번째 항목을 제외한 모든 항목을 무시하는 루프가 시작됩니다.
16진수를 10진수로 변환하여 출력합니다.
dd conv=unblock cbs=21 | while read x x x hexresult x x x ; do decimalresult=$(printf "%d" 0x${hexresult}) echo ${decimalresult} done
아직 연속 스트리밍을 시도하지 않았으므로 약간 조정이 필요할 수 있습니다. 특히 obs=21
매개변수를 추가해야 할 수도 있습니다 dd
(21이 아닌 20개일 수도 있음).