Question

I am working on a program that takes an axis value from a USB joystick and sends it over TCP. What I did is first get the TCP program working so I can send messages which was working as expected. Then I wrote another program to obtain the values from the joystick and print them to the screen which also worked as expected.

What I have recently attempted was to combine these two separate programs into one so I have a server program and a client program. That is where my problem has begun, I don't get any errors during compile. It seems that the program is no longer obtaining values from the joystick any longer and storing them in a variable axis[0].

Right now my process is to start the server.c file on the computer with the joystick attached. Then I will start the client.c file on the computer that is supposed to receive the values. I have several printf statements along the way to tell me where the script has gotten to so far. When I execute the server.c script it tells me the joystick is detected and had 6 axis and 12 buttons. It will then wait in a loop until a connection from the client is attempted.

Once the client.c program is executed it will print out the The value is -1093458243. Below that it will print out Incoming connection from 192.168.254.15 - sending welcome. The client program then quits and that is all that happens.

The line that says The value is: should be a number between -32768 and 32767. So it is getting a garbage value from somewhere. I am lost and have been trying to troubleshoot this for an entire day now with no luck. I have included several code examples, the working TCP server and client scripts along with the working joystick script with the code I have tried combining the two with. Can anyone spot any errors in my code, or give me some pointers?

Here is the combined code for server.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

//joysick libraries
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/joystick.h>

//Joysick device
#define JOY_DEV "/dev/input/js0"

//TCP Port number
#define PORTNUM 2343

int main(int argc, char *argv[])
{

//TCP connect
    struct sockaddr_in dest; /* socket info about the machine connecting to us */
    struct sockaddr_in serv; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUM);           /* set the server port number */    

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    /* bind serv information to mysocket */
    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));

    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, 1);
    int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);

//TCP variable
         char msg1[10];


//Joystick variables
        int xAxis;
    int yAxis;
        int xSpeed;
        int ySpeed;

//Joystick initialize
    int joy_fd, *axis=NULL, num_of_axis=0, num_of_buttons=0, x;
    char *button=NULL, name_of_joystick[80];
    struct js_event js;

    if( ( joy_fd = open( JOY_DEV , O_RDONLY)) == -1 )
    {
        printf( "Couldn't open joystick\n" );
        return -1;
    }

//Get number of axes, buttons and name of joystick. Print results to screen
        ioctl( joy_fd, JSIOCGAXES, &num_of_axis );
    ioctl( joy_fd, JSIOCGBUTTONS, &num_of_buttons );
    ioctl( joy_fd, JSIOCGNAME(80), &name_of_joystick );

    axis = (int *) calloc( num_of_axis, sizeof( int ) );
    button = (char *) calloc( num_of_buttons, sizeof( char ) );

    printf("Joystick detected: %s\n\t%d axis\n\t%d buttons\n\n"
        , name_of_joystick
        , num_of_axis
        , num_of_buttons );

//Use non blocking mode for joystick
    fcntl( joy_fd, F_SETFL, O_NONBLOCK );   /* use non-blocking mode */


    while(1) {
//Test to read joystick state
            /* read the joystick state */
        read(joy_fd, &js, sizeof(struct js_event));

            /* see what to do with the event */
        switch (js.type & ~JS_EVENT_INIT)
        {
            case JS_EVENT_AXIS:
                axis   [ js.number ] = js.value;
                break;
            case JS_EVENT_BUTTON:
                button [ js.number ] = js.value;
                break;
        }
//Give msg1 variable the value of axis[0]
    sprintf(msg1, "%d", axis[0]);

    //char msg1 = axis[0];
//TCP send
    while(consocket)
    {
    printf("Value is: %6d\n", axis[0]);
        printf("Incoming connection from %s - sending welcome\n", inet_ntoa(dest.sin_addr));
        send(consocket, msg1, strlen(msg1), 0); 
        consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    }

    close(consocket);
    close(mysocket);
    return EXIT_SUCCESS;

//Print joystick state to screen
    printf("Value is: %d", axis[0]);
    //printf(" \r");
    //fflush(stdout);   
    }


//Joystick close
    close( joy_fd );    /* too bad we never get here */
    return 0;

//TCP message
    //printf("Please enter info\n");
    //fgets(msg1, 20, stdin);

}

Here is the old working server.c file:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PORTNUM 2343

int main(int argc, char *argv[])
{
    char msg1[] = "Hello World !\n";

    struct sockaddr_in dest; /* socket info about the machine connecting to us */
    struct sockaddr_in serv; /* socket info about our server */
    int mysocket;            /* socket used to listen for incoming connections */
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));           /* zero the struct before filling the fields */
    serv.sin_family = AF_INET;                /* set the type of connection to TCP/IP */
    serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
    serv.sin_port = htons(PORTNUM);           /* set the server port number */    

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    /* bind serv information to mysocket */
    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));

    /* start listening, allowing a queue of up to 1 pending connection */
    listen(mysocket, 1);
    int consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);

    while(consocket)
    {
        printf("Incoming connection from %s - sending welcome\n", inet_ntoa(dest.sin_addr));
        send(consocket, msg1, strlen(msg1), 0); 
        consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
    }

    close(consocket);
    close(mysocket);
    return EXIT_SUCCESS;
}

Here is the client.c file:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define MAXRCVLEN 500
#define PORTNUM 2343

int main(int argc, char *argv[])
{
   char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */
   int len, mysocket;
   struct sockaddr_in dest; 

   mysocket = socket(AF_INET, SOCK_STREAM, 0);

   memset(&dest, 0, sizeof(dest));                /* zero the struct */
   dest.sin_family = AF_INET;
   dest.sin_addr.s_addr = inet_addr("192.168.254.16"); /* set destination IP number */ 
   dest.sin_port = htons(PORTNUM);                /* set destination port number */

   connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));

   len = recv(mysocket, buffer, MAXRCVLEN, 0);

   /* We have to null terminate the received data ourselves */
   buffer[len] = '\0';

   printf("Received %s (%d bytes).\n", buffer, len);

   close(mysocket);
   return EXIT_SUCCESS;
}

This is the joystick file that obtains the values and prints them to the screen:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/joystick.h>
#include <wiringPi.h>
#define JOY_DEV "/dev/input/js0"

int main()
{
    int xAxis;
    int yAxis;
        int xSpeed;
        int ySpeed;

    FILE *fp;
        fp = fopen("/dev/servoblaster","w");
        if (fp == NULL) {
        printf("Error opening file");
        exit(0);
    }

    int joy_fd, *axis=NULL, num_of_axis=0, num_of_buttons=0, x;
    char *button=NULL, name_of_joystick[80];
    struct js_event js;

    if( ( joy_fd = open( JOY_DEV , O_RDONLY)) == -1 )
    {
        printf( "Couldn't open joystick\n" );
        return -1;
    }

    ioctl( joy_fd, JSIOCGAXES, &num_of_axis );
    ioctl( joy_fd, JSIOCGBUTTONS, &num_of_buttons );
    ioctl( joy_fd, JSIOCGNAME(80), &name_of_joystick );

    axis = (int *) calloc( num_of_axis, sizeof( int ) );
    button = (char *) calloc( num_of_buttons, sizeof( char ) );

    printf("Joystick detected: %s\n\t%d axis\n\t%d buttons\n\n"
        , name_of_joystick
        , num_of_axis
        , num_of_buttons );

    fcntl( joy_fd, F_SETFL, O_NONBLOCK );   /* use non-blocking mode */

    while( 1 )  /* infinite loop */
    {

            /* read the joystick state */
        read(joy_fd, &js, sizeof(struct js_event));

            /* see what to do with the event */
        switch (js.type & ~JS_EVENT_INIT)
        {
            case JS_EVENT_AXIS:
                axis   [ js.number ] = js.value;
                break;
            case JS_EVENT_BUTTON:
                button [ js.number ] = js.value;
                break;
        }

            /* print the results */

        //printf( "X: %6d  Y: %6d  ", axis[0], axis[1] );


        int xAxis = axis[0] / 327;
        int yAxis = axis[1] / 327;
        int ySpeed = 150-0.3*yAxis;
        int xSpeed = 150-0.3*xAxis;
        printf( "X is equal to: %d  Y is equal to: %d  Y speed is: %d ", xAxis, yAxis, ySpeed);

        fprintf(fp, "2=%d\n", ySpeed);
        fprintf(fp, "1=%d\n", xSpeed);
            printf("  \r");
        fflush(stdout);
    }

    close( joy_fd );    /* too bad we never get here */
    return 0;
}
Was it helpful?

Solution

What looks a bit strange to me (and I think it could be a reason of your problems)

fcntl( joy_fd, F_SETFL, O_NONBLOCK );   /* use non-blocking mode */

while( 1 )  /* infinite loop */
{

        /* read the joystick state */
    read(joy_fd, &js, sizeof(struct js_event));

you are using non-blocking mode, but there is no check that read call actually read anything. Since it's non blocking it will return even if no data yet available from joystick device.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top