PLC 1141 - Read from Serial

Forum about PLCBUS devices & software.

Moderator: Digit

Post Reply
yammi
Starting Member
Starting Member
Posts: 1
Joined: Sat Sep 11, 2010 11:14 pm

PLC 1141 - Read from Serial

Post by yammi »

Hi

This is my first post here - I recently started to play around with PLC (1141+ - Serial) and right now I try to develop some C libs to work with the API.
I can send commands to the PLC and everything works fine but I also want to receive answers and here is where I got stuck.

When I open the device I can easily send commands - BUT when I try to read I don't get any answer (despite the ACK bit is set).
I am pretty sure my serial settings are wrong - so I assume the correct settings are those:

9600 BAUD
8N1
Canonical (meaning line-based - no need to process every byte)
Syncronous (so no Signal Handler is needed - answer will be sent right after command).

Here is what I am doing:

Open Serial at the beginning of the programm

Code: Select all

    struct termios tio;
    memset(&tio,0,sizeof(tio));
    tio.c_iflag=0;
    tio.c_oflag=0;
    tio.c_cflag = CS8|CREAD|CLOCAL; //8n1, 
    tio.c_lflag=0;
    tio.c_lflag |= ICANON;

    *fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK | O_SYNC );
    cfsetospeed(&tio,BAUDRATE); // Baudrate is B9600
    cfsetispeed(&tio,BAUDRATE);  // Baudrate is B9600

    tcsetattr(*fd,TCSANOW,&tio);

read and write functions

Code: Select all

int tty_read (int *fd, char *buffer, int size) {
    int ret;
    ret = read (*fd, buffer, size);

    if (ret < 0) {
        if (errno == EAGAIN) {
            printf("SERIAL EAGAIN ERROR\n");
            strerror(errno));
            return 0;
        } else {
            printf("SERIAL read error %d %s\n", errno,
            strerror(errno));
            return 0;
        }
    }
    if ( ret == 0 ) {
        printf ("read returned 0 byte\n");
        return 0;
    }
    return 1;
}

int tty_write (int *fd, char *buffer, int size){
    int ret;
    ret = write (*fd, buffer, size);
    return ret;
}

and here is the main code where I send some data to PLC and don't get any answer:

Code: Select all

    char buffer[10] = {STX,0x05,0xff,0x00,0x22,0x00,0x00,ETX}; // 0x22 means "ON" and "send ack"
    ret = tty_write(&serial_fd, buffer, sizeof(buffer));
    
    usleep(500000); // wait ...
    char read_buffer[100];
    memset(&read_buffer,0,sizeof(read_buffer));

    if  ( tty_read(&serial_fd, read_buffer, sizeof(read_buffer)) ) {
        if (read_buffer != NULL) {
            printf ("got feedback %d\n", sizeof(read_buffer));
            hexdump (read_buffer, sizeof(read_buffer)); // let me see it's hex code 
        } else {
            printf ("no feedback\n");
        }
    }
    else 
        printf ( "read failed\n" );
Reaction is - the Light turns on and the stdout says:

Code: Select all

SERIAL EAGAIN ERROR
SERIAL read error 11 Resource temporarily unavailable
read failed
Since I am playing around for a few days now without any clue how to solve this it would be really great if somebody has any ides :)

Bye,
yammi
steve2xyz
Starting Member
Starting Member
Posts: 34
Joined: Mon Feb 08, 2010 8:46 am

Re: PLC 1141 - Read from Serial

Post by steve2xyz »

You almost certainly don't want canonical mode. Try something like this:

Code: Select all

   struct termios sb;

   memset(&sb, '\0', sizeof(sb));
   sb.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | ISIG);
   sb.c_lflag = 0;
   sb.c_oflag = 0;
   sb.c_cc[VMIN] = 1;
   sb.c_cflag = CLOCAL | CS8 | CREAD | B9600
   tcsetattr(fd, TCSANOW, &sb);

Code: Select all

   if (read_buffer != NULL) {
This is always going to be true. I'd just examine the number of characters returned by the read call.

Cheers, Steve
Post Reply

Return to “PLCBUS Forum”