Is cat the only reliable command that can read data from serial?












2














I have a scale that continuously send data via serial port, 2 times per second. The only reliable way on reading this data happened to be cat command. The following works:



cat /dev/ttyUSB0


But the problem with cat is that, as it doesn't receive an EOF, it continues retrieving data. I've also tried head, read and tail.



head -1 /dev/ttyUSB0 | strings


works 'almost' everytime, but now and then shows old data, and only re-running cat command fixes it (?). The string after pipe retrieves only printable data.



read line < /dev/ttyUSB0 | echo $line


now and then retrieves data, but most of the time only shows an empty line.



tail -1 < /dev/ttyUSB0


just freezes, waiting for EOF, maybe?



My issue is that i need to write a bash script that can be called and "read" /dev/ttyUSB0 and retrieve data. I'm going to use head. But I'm wondering, as cat never fails, if there's a way to capture only one line of cat output and then stop it.



Note: the port configuration is 9600 baud, 1 start bit, 8 data bits, no parity, 2 stop bits. To set the port properly this is the command:



sudo stty -F /dev/ttyUSB0 9600 -parity cs8 cstopb









share|improve this question
















bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • Did you try dd ? It might work (with suitable options).
    – Basile Starynkevitch
    Jul 12 '17 at 16:38










  • Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
    – ivanivan
    Jul 12 '17 at 16:44










  • Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
    – thejavo
    Jul 12 '17 at 17:31










  • Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
    – agc
    Jul 12 '17 at 19:33
















2














I have a scale that continuously send data via serial port, 2 times per second. The only reliable way on reading this data happened to be cat command. The following works:



cat /dev/ttyUSB0


But the problem with cat is that, as it doesn't receive an EOF, it continues retrieving data. I've also tried head, read and tail.



head -1 /dev/ttyUSB0 | strings


works 'almost' everytime, but now and then shows old data, and only re-running cat command fixes it (?). The string after pipe retrieves only printable data.



read line < /dev/ttyUSB0 | echo $line


now and then retrieves data, but most of the time only shows an empty line.



tail -1 < /dev/ttyUSB0


just freezes, waiting for EOF, maybe?



My issue is that i need to write a bash script that can be called and "read" /dev/ttyUSB0 and retrieve data. I'm going to use head. But I'm wondering, as cat never fails, if there's a way to capture only one line of cat output and then stop it.



Note: the port configuration is 9600 baud, 1 start bit, 8 data bits, no parity, 2 stop bits. To set the port properly this is the command:



sudo stty -F /dev/ttyUSB0 9600 -parity cs8 cstopb









share|improve this question
















bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.















  • Did you try dd ? It might work (with suitable options).
    – Basile Starynkevitch
    Jul 12 '17 at 16:38










  • Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
    – ivanivan
    Jul 12 '17 at 16:44










  • Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
    – thejavo
    Jul 12 '17 at 17:31










  • Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
    – agc
    Jul 12 '17 at 19:33














2












2








2


1





I have a scale that continuously send data via serial port, 2 times per second. The only reliable way on reading this data happened to be cat command. The following works:



cat /dev/ttyUSB0


But the problem with cat is that, as it doesn't receive an EOF, it continues retrieving data. I've also tried head, read and tail.



head -1 /dev/ttyUSB0 | strings


works 'almost' everytime, but now and then shows old data, and only re-running cat command fixes it (?). The string after pipe retrieves only printable data.



read line < /dev/ttyUSB0 | echo $line


now and then retrieves data, but most of the time only shows an empty line.



tail -1 < /dev/ttyUSB0


just freezes, waiting for EOF, maybe?



My issue is that i need to write a bash script that can be called and "read" /dev/ttyUSB0 and retrieve data. I'm going to use head. But I'm wondering, as cat never fails, if there's a way to capture only one line of cat output and then stop it.



Note: the port configuration is 9600 baud, 1 start bit, 8 data bits, no parity, 2 stop bits. To set the port properly this is the command:



sudo stty -F /dev/ttyUSB0 9600 -parity cs8 cstopb









share|improve this question















I have a scale that continuously send data via serial port, 2 times per second. The only reliable way on reading this data happened to be cat command. The following works:



cat /dev/ttyUSB0


But the problem with cat is that, as it doesn't receive an EOF, it continues retrieving data. I've also tried head, read and tail.



head -1 /dev/ttyUSB0 | strings


works 'almost' everytime, but now and then shows old data, and only re-running cat command fixes it (?). The string after pipe retrieves only printable data.



read line < /dev/ttyUSB0 | echo $line


now and then retrieves data, but most of the time only shows an empty line.



tail -1 < /dev/ttyUSB0


just freezes, waiting for EOF, maybe?



My issue is that i need to write a bash script that can be called and "read" /dev/ttyUSB0 and retrieve data. I'm going to use head. But I'm wondering, as cat never fails, if there's a way to capture only one line of cat output and then stop it.



Note: the port configuration is 9600 baud, 1 start bit, 8 data bits, no parity, 2 stop bits. To set the port properly this is the command:



sudo stty -F /dev/ttyUSB0 9600 -parity cs8 cstopb






command-line tty cat serial-port head






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 12 '17 at 21:22









Jeff Schaller

39.2k1054125




39.2k1054125










asked Jul 12 '17 at 16:14









thejavothejavo

1113




1113





bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







bumped to the homepage by Community 2 days ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.














  • Did you try dd ? It might work (with suitable options).
    – Basile Starynkevitch
    Jul 12 '17 at 16:38










  • Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
    – ivanivan
    Jul 12 '17 at 16:44










  • Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
    – thejavo
    Jul 12 '17 at 17:31










  • Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
    – agc
    Jul 12 '17 at 19:33


















  • Did you try dd ? It might work (with suitable options).
    – Basile Starynkevitch
    Jul 12 '17 at 16:38










  • Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
    – ivanivan
    Jul 12 '17 at 16:44










  • Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
    – thejavo
    Jul 12 '17 at 17:31










  • Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
    – agc
    Jul 12 '17 at 19:33
















Did you try dd ? It might work (with suitable options).
– Basile Starynkevitch
Jul 12 '17 at 16:38




Did you try dd ? It might work (with suitable options).
– Basile Starynkevitch
Jul 12 '17 at 16:38












Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
– ivanivan
Jul 12 '17 at 16:44




Your head command may be getting slightly old data due to a buffer, and you are reading the top of it. When you tried tail, it was with other arguments. Try repeating the head command options with tail
– ivanivan
Jul 12 '17 at 16:44












Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
– thejavo
Jul 12 '17 at 17:31




Thank Basile, I'll investigate dd. Ivan, I agree with you. I've assumed that I'm reading some kind of buffer of stdout. ¿is there a way to reset it?. And don't understand why cat isn't affected with this buffer issue. Thank you. I've used head -10 /dev/ttyUSB0 | tail -1. But get the same result, erratic.
– thejavo
Jul 12 '17 at 17:31












Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
– agc
Jul 12 '17 at 19:33




Try prefixing a non-cat command with stdbuf -i 0 -o 0, i.e. stdbuf -i 0 -o 0 head -1 /dev/ttyUSB0 | strings.
– agc
Jul 12 '17 at 19:33










1 Answer
1






active

oldest

votes


















0














Your best bet is to place the tty in raw mode, and write a program that discards characters until it sees the start of a message, and then prints characters until it reaches the end of a message. With 'raw' added to the stty, fgetc() can be used on the tty to get a single character.



off the cuff psuedo:



char = fgetc(serial_port);
if char == START_CHARACTER {
putc(char);
for (i=0;i<MESSAGE_LENGTH;i++){
putc(fgetc(serial_port));
}
}


It may also be possible to do this with sed and a raw tty, see this other question:
https://stackoverflow.com/questions/20943025/how-can-i-get-sed-to-quit-after-the-first-matching-address-range






share|improve this answer























  • thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
    – thejavo
    Jul 14 '17 at 12:48











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f378010%2fis-cat-the-only-reliable-command-that-can-read-data-from-serial%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Your best bet is to place the tty in raw mode, and write a program that discards characters until it sees the start of a message, and then prints characters until it reaches the end of a message. With 'raw' added to the stty, fgetc() can be used on the tty to get a single character.



off the cuff psuedo:



char = fgetc(serial_port);
if char == START_CHARACTER {
putc(char);
for (i=0;i<MESSAGE_LENGTH;i++){
putc(fgetc(serial_port));
}
}


It may also be possible to do this with sed and a raw tty, see this other question:
https://stackoverflow.com/questions/20943025/how-can-i-get-sed-to-quit-after-the-first-matching-address-range






share|improve this answer























  • thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
    – thejavo
    Jul 14 '17 at 12:48
















0














Your best bet is to place the tty in raw mode, and write a program that discards characters until it sees the start of a message, and then prints characters until it reaches the end of a message. With 'raw' added to the stty, fgetc() can be used on the tty to get a single character.



off the cuff psuedo:



char = fgetc(serial_port);
if char == START_CHARACTER {
putc(char);
for (i=0;i<MESSAGE_LENGTH;i++){
putc(fgetc(serial_port));
}
}


It may also be possible to do this with sed and a raw tty, see this other question:
https://stackoverflow.com/questions/20943025/how-can-i-get-sed-to-quit-after-the-first-matching-address-range






share|improve this answer























  • thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
    – thejavo
    Jul 14 '17 at 12:48














0












0








0






Your best bet is to place the tty in raw mode, and write a program that discards characters until it sees the start of a message, and then prints characters until it reaches the end of a message. With 'raw' added to the stty, fgetc() can be used on the tty to get a single character.



off the cuff psuedo:



char = fgetc(serial_port);
if char == START_CHARACTER {
putc(char);
for (i=0;i<MESSAGE_LENGTH;i++){
putc(fgetc(serial_port));
}
}


It may also be possible to do this with sed and a raw tty, see this other question:
https://stackoverflow.com/questions/20943025/how-can-i-get-sed-to-quit-after-the-first-matching-address-range






share|improve this answer














Your best bet is to place the tty in raw mode, and write a program that discards characters until it sees the start of a message, and then prints characters until it reaches the end of a message. With 'raw' added to the stty, fgetc() can be used on the tty to get a single character.



off the cuff psuedo:



char = fgetc(serial_port);
if char == START_CHARACTER {
putc(char);
for (i=0;i<MESSAGE_LENGTH;i++){
putc(fgetc(serial_port));
}
}


It may also be possible to do this with sed and a raw tty, see this other question:
https://stackoverflow.com/questions/20943025/how-can-i-get-sed-to-quit-after-the-first-matching-address-range







share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 28 '18 at 8:04









chaos

35.1k773116




35.1k773116










answered Jul 12 '17 at 20:40









KJ4IPSKJ4IPS

1643




1643












  • thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
    – thejavo
    Jul 14 '17 at 12:48


















  • thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
    – thejavo
    Jul 14 '17 at 12:48
















thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
– thejavo
Jul 14 '17 at 12:48




thanks you very much KJ4IPS!, i'll try not to "sound" rude, but I lack the vocabulary to "sound polite enough", so excuse me. But the answer you've wrote doesn't solve my problem. The scale already transmits data with 2Hz frequency. Inmediately after been turned on. Constantly. It never stops. So it's not possible to reach an end of message. On the other hand, I'm interested in solving this with pure bash.
– thejavo
Jul 14 '17 at 12:48


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f378010%2fis-cat-the-only-reliable-command-that-can-read-data-from-serial%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

is 'sed' thread safe

How to make a Squid Proxy server?