iainmaoileoin
Posts: 16
Joined: Tue Jul 31, 2012 10:57 pm

non blocking input from keyboard

Thu Nov 22, 2012 9:44 am

I ssh in to my pi and want to control stepper motors from the keyboard while dev/testing.
I dev in C (lots of grey hair here) not snake oil python.

Using
int fd, n;
char c;
fd = open("/dev/tty", O_RDWR | O_NONBLOCK);
I can get a
n=read(fd,&c,1);
to return -1 when no data is waiting but a positive number when I have data.
Each character I type is delivered 1 at a time in "c".

The only trouble is that I need to type a return to get the data into program.
How do I make input non_blocking and character at a time. There must be a way to switch off
the return being needed on non-blocking input?


(note I am using /dev/tty NOT the uart serial cable.

I have a few nema 23 motors running great off the GPIO pins on the pi. The logic signals can feed straight into a 1 axis driver board I got off ebay. The driver board runs ok on 3.3V since the pullup is to 3.3 and the grounding of the signal is used to drive the step and direction logic ;-)

User avatar
joan
Posts: 15039
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: non blocking input from keyboard

Thu Nov 22, 2012 9:55 am

Various code snippets. Among them you should find what you need.

Code: Select all

struct termios orig_termios;

void reset_terminal_mode()
{
    tcsetattr(0, TCSANOW, &orig_termios);
}

void set_conio_terminal_mode()
{
    struct termios new_termios;

    /* take two copies - one for now, one for later */
    tcgetattr(0, &orig_termios);
    memcpy(&new_termios, &orig_termios, sizeof(new_termios));

    /* register cleanup handler, and set the new terminal mode */
    atexit(reset_terminal_mode);
    cfmakeraw(&new_termios);
    tcsetattr(0, TCSANOW, &new_termios);
}

int dataRdy(int fd)
{
    struct timeval tv = { 0L, 0L };
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd, &fds);
    return select(fd+1, &fds, NULL, NULL, &tv);
}

int getch()
{
    int r;
    unsigned char c;
    if ((r = read(0, &c, sizeof(c))) < 0)
    {
        return r;
    }
    else
    {
        return c;
    }
}

/* initialisation */

   set_conio_terminal_mode();


iainmaoileoin
Posts: 16
Joined: Tue Jul 31, 2012 10:57 pm

Re: non blocking input from keyboard

Thu Nov 22, 2012 10:05 am

Joan THANKS
I did have to add
#include <termios.h>
which I was not including;

Apart from that it worked first time.
I has been over 3 decades since I last did termio stuff :oops:

I also had to go dust down my rs232 breakout box to drive some other stepper motors.
It all comes round again

iainmaoileoin
Posts: 16
Joined: Tue Jul 31, 2012 10:57 pm

Re: non blocking input from keyboard

Thu Nov 22, 2012 11:12 am

I dont know how to edit posts, so this is related to the one above.
When the termio is applied the controlling console (/dev/tty) goes into raw mode. A
consequence of this is that "\n" in printfs(etc) only does what it is told and prints a linefeed. So you get staircase output.
You have to do a "\r\n" instead of a "\n" to get conventional screen like output.

I guess you are saying I should use "[n]curses" rather than do it myself?

Return to “Beginners”