I am trying to control servos from C++ code on an Odroid-U2. I have the SSC-32 servo driver from LynxMotion attached to the Odroid using a Usb-Serial cord.
Simple serial commands control the servos, such as "#n Puuu" followed by carriage return, where n=pin number for the servo, and uuu=pulse width. I am able to control the servos fine when using PUTTY from the Odroid, but I have been having issues when using C++ code to control the servos. For example, in my code I do the following:
fstream f;
f.open("/dev/ttyUSB0");
f << "#0 P600\r";
f.close();
At one time, I was able to run this code and it wiggled the servo appropriately, but now the terminal gets stuck and hangs still when I try to run this code. I narrowed the problem down to the f.open("/dev/ttyUSB0") line, which prevents the code from running. I'm assuming I need to configure the USB port in some way. I know I need a baudrate of 115200, and have set it accordingly, but I'm kind of a Ubuntu n00b, so I'm not sure what other types of configurations I need.
My version of Linux is Linaro 12.11.
When I type stty, the non-default configurations set seem to be:
speed 115200 baud; line = 0;
-brkint ixoff -imaxbel
-iexten
You cannot rely on the default settings of your serial port (and you should not try to use stty to set them up outside of your program). You have to write code into your program that sets your serial port up properly. For this, you have to use functions like tcsetattr/tcgetattr, cfsetspeed, etc., see man termios.
Also, fstream might not provide access to the proper open() function parameters to use, as opening a serial port on UNIX should be done with O_NOCTTY flag.
Related
Qt "Terminal Example" is not working as expected with RS232.
I am using this as a boilerplate for my serial GUI application but cannot get it to send data to my device. Using the same settings in PUTTY I get a perfect output. I have narrowed it down to the issue that it will only send a single message and then no more. Is there some loop in there? I've already put debug statements all over to check unknown actions with no luck.
I checked what functions are outputting but I cannot see anywhere that it closes the port.
I also thought that maybe it was just me not sending the \r command but even this did nothing. I simply send the first message and then it does nothing.
I have tried sending it manually, with commands like these:
m_serial->write("command");
m_serial->write("command\r");
I have also tried following a solution here: How to make QSerialPort from Qt5.13.1 work?
I tried to update to the newest version and the maintenance tool did not find repository so I just did a clean install with 5.12.5 and same problem persists.
In my image, the first set of open-close is the terminal example. The second set is Putty working. I am definitely connecting because the error checking and serial port info I get from Qt is correct.
EDIT
My port settings are:
Baud: 9600
Data bits: 8
Stop Bits: 1
Parity: None
Flow Control: None
Qt Version: 5.13.1, 5.12.5
Hello dear Communauts,
I'm am creating a terminal animated status report for a parallel software I'm developing. I'm using NCurses.
I'm having an issue related to the restoring of the standard behavior of the terminal.
After running my software the terminal keeps having just 24 lines, no matter if I call endwin() or I don't.
Here the simplified code:
int size=10;
initscr();
refresh();
while(KeepAlive){
int j=1;
mvprintw(j,0,/*Blah blah header*/));
for(int i=0;i<size;i++){
j++;
mvprintw(j,0,/*Some blah blah*/);
}
refresh();
usleep(1000000);
}
endwin();
KeepAlive is a control variable changed by another thread (so the while is not infinite loop, but controlled loop).
After running this software my terminal has only 24 lines, echo works, but there's plenty of blank space.
Thanks a lot for your help, have fun
EDIT:
I would like to share with you some information I found while attempting to solve my issue:
curses (ncurses) is perfectly working under openMP, then you can imagine some threads doing your math calculations and one thread (only one, be aware) giving out some runtime infos.
curse (ncurses) is NOT compatible with MPI. Well, the right stating would be is "not completely" compatible with MPI. MPI is really sophisticated about stdin/stdout/stderr, since all outputs from all MPI-processes could be redirected to a display (which could be specified). Using any advanced terminal output overriding library will take to a fault of the code, or unexpected behaviors.
That's supported by the MPI faq:
Maybe. But probably not.
Open MPI provides fairly sophisticated stdin / stdout / stderr forwarding. >However, it does not work well with curses, ncurses, readline, or other >sophisticated I/O packages that generally require direct control of the terminal.
Every application and I/O library is different -- you should try to see if yours >is supported. But chances are that it won't work.
Sorry. :-(
found here (MPI reference).
What I've discovered is that even if you appoint only one MPI-process to manage all the curses output (just that process calls initscr() at the beginning and endwin() at the end of his part of code) there is no way to force curses to use the full terminal (only default UNIX 24x80 will be available).
Once MPI has been finalized your whole terminal will keep working in 24x80 mode until reset is called.
Thanks to all communauts that helped me,
Have fun
gf
One possible solution is to completely decouple your text GUI from the rest of the MPI code and make both parts talk to each other via the client/server mechanism of MPI-2. That means:
Run the GUI as singleton MPI program, i.e. one that calls MPI_Init{_thread} but is not started via mpiexec. It then should open a listening port by calling MPI_Open_port. The call returns a string port name that has to be supplied to the compute part of the application. The GUI part should then start listening for connections by calling the blocking MPI_Comm_accept.
The compute part is started as usual via mpiexec. It should connect to the GUI by calling MPI_Comm_connect given the port name from (1).
The combination of MPI_Comm_accept in the GUI and MPI_Comm_connect in the compute part establishes an intercommunicator that can be used for sending messages between the two parts. The compute part could e.g. send periodic status messages to the GUI. If necessary, the intercommunicator could be further "flattened" to an intracommunicator.
Once the computation is finished, the communication part should disconnect by calling MPI_Comm_disconnect.
The GUI should call MPI_Close_port and finish its own execution.
In that scenario, the GUI part could be a text mode curses application started locally or remotely via SSH, an X11 GUI application, or whatever else there.
It should work. The comment about "parallel" suggests multithreading, which can mean that your output is not flushed as one might expect.
Likely this is the same issue (Ncurses limited output size) for which more information was given. Neither question provides enough detail to offer more than generic advice.
I want to open a ssh session to my Raspberry Pi and run simple command echo 0=+10 > /dev/servoblaster at what time I want ( means not using system("ssh pi#192.168.1.5 echo 0=+10 > /dev/servoblaster") because it takes time to run ssh again). What is the easiest way in C++?
Assuming you only need one-way communication, open the ssh connection with FILE *ssh = popen("ssh pi#192.168.1.5", "w") instead of system. That will give you a handle to write to, e.g. fprintf(ssh, "echo 0=%#d > /dev/servoblaster", 10);. The ssh connection is then avilable until you pclose(ssh); at some later point.
If you need to read back, you will need to open both sides of a pipe, which requires a "proper fork jobbie". You could perhaps start with this example, in that case.
fork() and pipes() in c
For sending simple control commands, ssh is an overkill to say the least.
People usually use the simple serial port for that. This can be done in several ways, using libraries like QtSerialPort or just go through the manual termios settings.
You could use "gserial" for getting serial port operation over the USB connection and use it as a regular serial port.
I have not used it but it looks promising.
http://api.libssh.org/master/libssh_tutor_guided_tour.html
I'm writing a C++ program to control servo motor by Raspberry Pi with command above, and how can I access and run command to Raspberry Pi without ssh ?
You can access and run commands to control servo motor by Raspberry Pi, using REST API provided by WebIOPi.
I'm wondering how to programmatically change to one of the available terminals from an embedded Qt application.
The application is invoked via application -qws. Graphically it is configured with the Linux framebuffer (support compiled into the kernel) with the tty drivers enabled.
The reason for doing this programmatically is that Ctrl+Alt+FX does not work to switch ttys.
Firstly, I tried the obvious cheating mechanism - overriding keyPressEvent I added system("chvt 2"); Unfortunately, this did not work.
Instead, I looked directly at the source of chvt.c in busybox. Essentially, that boiled down to doing:
fd = open("/dev/console", O_RDRW);
ioctl(fd, VT_ACTIVATE, vt_num);
ioctl(fd, VT_WAITACTIVE, vt_num);
Ignoring the use of xioctl and detecting the correct tty - I know /dev/console exists and I can get a RW file handle on it.
Again, no luck.
So taking my cue from chvt.c I decided to iterate over all the framebuffer devices present until I found one that was receiving keyboard input; then I ran
fd = open("/dev/fb1", O_RDRW);
ioctl(fd, VT_ACTIVATE, vt_num);
ioctl(fd, VT_WAITACTIVE, vt_num);
That caused a black screen as per any normal tty change, except that the framebuffer device returned afterwards, bringing my app back with it.
So - my question - without exiting my application, I'd like to be able to programmatically switch to a tty of my choice, and then be able to switch back using the usual ctrl+alt+fX mechanism.
Environment:
Qt 4.7.4
Linux 3.3.3
Buildroot 2011.11
Busybox 1.19
uClibc 2.21
I suspect, but am not certain, that the cause of ctrl+alt+fX not working in the first place may be the cause of the tty change not working programmatically as per chvt.
I should point out at this stage that, confusingly, the zap keys (ctrl+alt+backspace) do work as expected.
In C/C++ how can my programs determine if there is a desktop (system or remote) or not?
My project has three separate programs running (now) in separate gnome-terminals. It is launched by the last line of .profile, so it starts whether I am at the system desktop (gnome) or remotely connecting by VPN/telnet or VPN/remote-desktop. My machine is 250 miles away at a test site, so I frequently login remotely to make changes and have to restart the program.
I'd like my program to be able to detect that it is launched from a desktop environment or from a telnet session. Preferably, I want them to continue running after the remote connection is broken.
Obviously, I need to make my programs into daemons so they will persist after I close the connection. But if I start them in a terminal on a desktop environment, where I can actually have three terminals open, I'd like to watch their progress messages. And if I disconnect the remote desktop, I'd like the daemons to detect this and turn off printing (to the now killed terms) but keep on running in normal (silent) daemon mode. Best of all, the programs could recheck for a desktop occasionally and resume printing by opening new terminals.
Is this possible? Any coding suggestions?
Thanks in advance.
You can use the isatty function. Detect if stdin is a terminal or pipe?
#include <stdio.h>
#include <io.h>
//...
if (isatty(fileno(stdin)))
printf( "stdin is a terminaln" );
else
printf( "stdin is a file or a pipen");
You can find more information at http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_12.html
Some more code: http://pastebin.com/S3Lr9tik
The traditional solution for this problem is an option in the command
line. Such programs will typically demonize themselves unless given a
special debug option telling them not to.
Another solution would be to use a shell script to start the program as
a demon, via the nohup command (and redirecting standard input and
output to /dev/null).
As for determining whether your managing terminal is local or not, it
could be difficult; both X and telnet use virtual terminals, so if
you're running under X, you may not be able to distinguish between a
telnet session and a local xterm window. Still, it might be worth
trying... Under Linux, /proc/<procid>/fd/0 is a symbolic link to the
device connected to standard in (fd 0): using something like readlink,
you should be able to determine the actual name. Or fstat will give
you the major and minor numbers of the device. Given these, you might
be able to determine which is which. If your local terminal is not
under X, but a real terminal, it will definitely have a different minor
number than a pseudo-terminal. For xterms, it's possible that the minor
numbers of the pseudo-terminals fall in different ranges, or even that
there are distinct sets of pseudo-terminals for remote links and for X;
you'll probably have to experiment some, and there might be no working
solution. (For starters, to tty at each terminal, and see what it
says. I don't have local access to a Linux machine to check, but I seem
to remember that on Solaris, X terminals had names like /dev/ttyxx; my
remote terminals on Linux here are /dev/pts/xx. (Where xx is a
number in each case.)