Use serial-console as display, but computer keyboard for standard-input - linux

I have a 40x7 VFD that functions as a serial terminal. It has a dedicated keypad that provides hex-entry, however, I would like to use a keyboard for the standard input. Basically, I want to be able to use the VFD as a display for a Linux bash prompt, but use the keyboard connected to the computer as the means of input. Instead of connecting a monitor, the serial terminal will be the monitor. I can get the login prompt displayed on the VFD with agetty, but since it only has hex-entry, how can I change where the system is looking for standard input?
Thanks,
Core_Module

I think the best method would be to create a pseudo terminal. In doing so you create a fake terminal device with a /dev/pts/[n] name that acts like a real input/output device. A program could connect the console (keyboard) as input and the VFD as output and send and receive that data over the pseudo device. You can then point agetty at the /dev/pts/[0] device instead of a /dev/ttyS[n] device. Some ideas on doing this can be found in many tutorials online. From the link:
A pseudo-terminal is a pair of character mode devices also called pty. One is master and the other is slave and they are connected with a bidirectional channel. Any data written on the slave side is forwarded to the output of the master side. Conversely, any data written on the master side is forwarded to the output of the slave.
I found another StackOverflow question that may also be of assistance. See this link. It could be adapted to suit your needs.

Related

Why can't I read in a freshly opened TTY in Raspbian

I have a small issue with my code, running in Python 3. I'm trying to fool Raspbian, in order to make it believe a tty is an external device.
However, I can't read a single word I wrote previously with os.write(slave, text.encode()), using something like os.read(slave, 512).
I open the tty as follow master, slave = os.openpty()
I think I'm missing a parameter or something, but I can't find out what.
I tried accessing the tty in another terminal, with a cat <, with a subprocess, but the program still block when it has to read.
Please explain what is the problem.
Regards.
I think your mistake here is that you are trying to read the slave. If you read the master instead you should get your output.
Quote from: http://www.rkoucha.fr/tech_corner/pty_pdip.html
A pseudo-terminal is a pair of character mode devices also called pty. One is master and the other is slave and they are connected with a bidirectional channel. Any data written on the slave side is forwarded to the output of the master side. Conversely, any data written on the master side is forwarded to the output of the slave side as depicted in figure 2.
RPI

Epson projector

I have a projector that can accept control commands like turn on/off and queries like amount of time it was on.
Control commands work, but I can't seem to capture responses from queries; when I connect via USB, I get two additional raw input files in the dev directory.
I wrote a C program that captures events from input devices it captures mouse movements and keyboard events, but it doesn't capture replies from the projector at all, not even the event itself. Why is that?
In Windows, everything works.

testing serial connections using screen

I have two usb to serial cables collected to a null modem and then the two usb connections connected two seperate usb ports on my linux machine
I want to write a program that allows them to communicate back and forth through a terminal, and wanted to test the two ports using screen
I type screen ttyUSB0 115200 but it just comes up with a blank terminal with no text, i realize i am supposed to use commands but I cant find a guide anywhere on how to use this to test to make sure the serial ports are sending/receiving data among other things, could someone point me in the right direction?
I have two usb to serial cables ...
Those are not just "cables", but rather adapters.
Besides the copper wire, there is an IC with a microprocessor, RAM, and ROM inside that dongle. Your PC will recognize each USB-to-serial adapter as a (USB-based) serial port.
IOW you have two serial ports.
Therefore you need two (not just one) instances of a terminal emulator program (e.g. screen), one for each serial port.
Unless you have both terminals perfectly configured, you may have confusing issues such as no echo (what you type shows up in the other terminal, but is not displayed in the terminal where you're typing), and the Enter key only responds as a new line with vertical movement of the cursor and no horizontal movement.
I want to write a program that allows them to communicate back and forth ...
That's possible so long as you open() both serial terminal devices.

Serial port determinism

This seems like a simple question, but it is difficult to search for. I need to interface with a device over the serial port. In the event my program (or another) does not finish writing a command to the device, how do I ensure the next run of the program can successfully send a command?
Example:
The foo program runs and begins writing "A_VERY_LONG_COMMAND"
The user terminates the program, but the program has only written, "A_VERY"
The user runs the program again, and the command is resent. Except, the device sees "A_VERYA_VERY_LONG_COMMAND," which isn't what we want.
Is there any way to make this more deterministic? Serial port programming feels very out-of-control due to issues like this.
The required method depends on the device.
Serial ports have additional control signal lines as well as the serial data line; perhaps one of them will reset the device's input. I've never done serial port programming but I think ioctl() handles this.
There may be a single byte which will reset, e.g. some control character.
There might be a timing-based signal, e.g. Hayes command set modems use “pause +++ pause”.
It might just reset after not receiving a complete command after a fixed time.
It might be useful to know whether the device was originally intended to support interactive use (serial terminal), control by a program, or both.
I would guess that if you call write("A_VERY_LONG_COMMAND"), and then the user hits Ctrl+C while the bytes are going out on the line, the driver layer should finish sending the full buffer. And if the user interrupts in the middle of the call, the driver layer will probably just ignore the whole thing.
Just in case, when you open a new COM port, it's always wise to clear the port.
Do you have control over the device end? It might make sense to implement a timeout to make the device ignore unfinished or otherwise corrupt packets.
The embedded device should be implemented such that you can either send an abort/clear/break character that will dump the contents of its command buffer and give you a clean slate on your client app startup.
Or else it should provide a software reset character which will reset the command buffer and all state.
Or else it so be designed so that you can send a command termination (perhaps a newline, etc, depending on command protocol) and possibly have an error generated on the parsing of a garbled partial command that was in its buffer, query/clear the error, and then be good to go.
It wouldn't be a bad idea upon connection of your client program to send some health/status/error query repeatedly until you get a sound response, and only then commence sending configuration or operation commands. Unless you can via a query determine that the device was left in a suitable state, you probably want to assume nothing and configure it from scratch, after a configuration reset if available.

How can I monitor data on a serial port in Linux?

I'm debugging communications with a serial device, and I need to see all the data flowing both directions.
It seems like this should be easy on Linux, where the serial port is represented by a file. Is there some way that I can do a sort of "bi-directional tee", where I tell my program to connect to a pipe that copies the data to a file and also shuffles it to/from the actual serial port device?
I think I might even know how to write such a beast, but it seems non-trivial, especially to get all of the ioctls passed through for port configuration, etc.
Has anyone already built such a thing? It seems too useful (for people debugging serial device drivers) not to exist already.
strace is very useful for this. You have a visualisation of all ioctl calls, with the corresponding structure decoded. The following options seems particularly useful in your case:
-e read=set
Perform a full hexadecimal and ASCII dump of all the data read from
file descriptors listed in the
specified set. For example, to see all
input activity on file descriptors 3
and 5 use -e read=3,5. Note that this
is independent from the normal tracing
of the read(2) system call which is
controlled by the option -e
trace=read.
-e write=set
Perform a full hexadecimal and ASCII
dump of all the data written to file
descriptors listed in the specified
set. For example, to see all output
activity on file descriptors 3 and 5
use -e write=3,5. Note that this is
independent from the normal tracing of
the write(2) system call which is
controlled by the option -e
trace=write.
I have found pyserial to be quite usable, so if you're into Python it shouldn't be too hard to write such a thing.
A simple method would be to write an application which opened
the master side of a pty and the tty under test. You would then
pass your tty application the slave side of the pty as the 'tty device'.
You would have to monitor the pty attributes with tcgetattr() on the pty
master and call tcsetattr() on the real tty, if the attributes changed.
The rest would be a simple select() on both fd's copying data bi-directionally and copying it to a log.
I looked at a lot of serial sniffers. All of them are based on the idea of making a virtual serial port and sniff data from that port. However, any baud/parity/flow changes will break connection.
So, I wrote my own sniffer :). Most of the serial ports now are just USB-to-serial converters. My sniffer collects data from USB through debugfs, parse it and output to the console. Also any baudrate changes, flow control, line events, and serial errors are also recorded. The project is in the early stage of development and for now, only FTDI is supported.
http://code.google.com/p/uscmon/
Much like #MBR, I was looking into serial sniffers, but the ptys broke the parity check. However, his sniffer was not helping me, as I'm using a CP2102, and not a FT232. So I wrote my own sniffer, by following this, and now I have one that can record file I/O on arbitrary files: I called it tracie.

Resources