Connecting to USB serial port on my Leonardo

I'm using a USB 2.0 to TTL UART 6PIN CP2102 Module Serial Converter to connect my Leonardo to my Fedora29 box.

I have RX & TX plugged into pins 0 & 1 plus GND is plugged in. No other pins are plugged in.

I'm using the SoftwareSerialExample sketch plus modifications:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600); //57600);
  
 /*
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
*/

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write("HELLO!"); //mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write("HELLO again!!!"); //Serial.read());
  }
}

On the Linux side I've written a piece of C code that polls on /dev/ttyUSB0:

#include <stdio.h>  
#include <string.h>
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h>  
#include <sys/stat.h>   
#include <fcntl.h>  
#include <termios.h>    
#include <errno.h> 

#include <sys/poll.h>
#include <linux/serial.h>

#define FALSE 0
#define TRUE 1

void set_speed(int fd) {
    struct termios opt;
    
    tcgetattr(fd, &opt);
    cfsetispeed(&opt, B9600);
    cfsetospeed(&opt, B9600);
    tcsetattr(fd, TCSANOW, &opt);
}

void set_parity(int fd) {
    struct termios tty;
    
    tcgetattr(fd, &tty);

    tty.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /* c_iflag input modes */
    tty.c_oflag  &= ~OPOST;   /* c_oflag output modes */

    tty.c_cflag |= (CLOCAL | CREAD);    /* c_cflag control modes */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */
    
    tcsetattr(fd, TCSANOW, &tty);
}

int OpenSerial(char *dev) {
    int fd = open( dev, O_RDWR );         //| O_NOCTTY | O_NDELAY
    
    if (-1 == fd) {
        perror("Can't Open Serial Port");
        return -1;
    }

    set_speed(fd);
    set_parity(fd);

    return fd;
}

int main(void) {
  
    struct pollfd fds[1];
    ssize_t length;
    char buff[512];
    char *dev = "/dev/ttyUSB0";

    fds[0].fd = OpenSerial(dev);
    fds[0].events = POLLIN ;
    while (TRUE) {
        int n;
        n = poll( fds, 1, 5000);
        //got data, and look up which fd has data, but we just have 1
        if(n > 0) {
        //if( fds[0].revents & POLLIN ) {
            length = read(fds[0].fd, buff, sizeof(buff) );
            buff[length] = 0;
            printf("poll:%s\n",buff);

        } else {
            printf("No data within 5 seconds.\n");
        }
    }
}

I'm simply writing to the serial port on the Leonardo side and reading from the port /dev/ttyUSB0 on the Fedora side.

All to no avail.
Any ideas?

I'm using a USB 2.0 to TTL UART 6PIN CP2102 Module Serial Converter to connect my Leonardo to my Fedora29 box.

I have RX & TX plugged into pins 0 & 1 plus GND is plugged in. No other pins are plugged in.

I'm using the SoftwareSerialExample sketch plus modifications:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600); //57600);
  
 /*
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
*/

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write("HELLO!"); //mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write("HELLO again!!!"); //Serial.read());
  }
}

On the Linux side I've written a piece of C code that polls on /dev/ttyUSB0:

#include <stdio.h>  
#include <string.h>
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h>  
#include <sys/stat.h>   
#include <fcntl.h>  
#include <termios.h>    
#include <errno.h> 

#include <sys/poll.h>
#include <linux/serial.h>

#define FALSE 0
#define TRUE 1

void set_speed(int fd) {
    struct termios opt;
    
    tcgetattr(fd, &opt);
    cfsetispeed(&opt, B9600);
    cfsetospeed(&opt, B9600);
    tcsetattr(fd, TCSANOW, &opt);
}

void set_parity(int fd) {
    struct termios tty;
    
    tcgetattr(fd, &tty);

    tty.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /* c_iflag input modes */
    tty.c_oflag  &= ~OPOST;   /* c_oflag output modes */

    tty.c_cflag |= (CLOCAL | CREAD);    /* c_cflag control modes */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */
    
    tcsetattr(fd, TCSANOW, &tty);
}

int OpenSerial(char *dev) {
    int fd = open( dev, O_RDWR );         //| O_NOCTTY | O_NDELAY
    
    if (-1 == fd) {
        perror("Can't Open Serial Port");
        return -1;
    }

    set_speed(fd);
    set_parity(fd);

    return fd;
}

int main(void) {
  
    struct pollfd fds[1];
    ssize_t length;
    char buff[512];
    char *dev = "/dev/ttyUSB0";

    fds[0].fd = OpenSerial(dev);
    fds[0].events = POLLIN ;
    for(;;) {
        int n;
        n = poll( fds, 1, 5000);
        //got data, and look up which fd has data, but we just have 1
        if(n > 0) {
        //if( fds[0].revents & POLLIN ) {
            length = read(fds[0].fd, buff, sizeof(buff) );
            buff[length] = 0;
            printf("poll:%s\n",buff);

        } else {
            printf("No data within 5 seconds.\n");
        }
    }
}

I'm simply writing to the serial port on the Leonardo side and reading from the port /dev/ttyUSB0 on the Fedora side.

All to no avail.
Any ideas?

You don't need to use SoftwareSerial on a Leonardo. Pins 0 and 1 are a separate HardwareSerial connection called Serial1.

Post a link to the datasheet for your USB-TTL device.

Are you connecting Rx to Tx and Tx to Rx ?

...R

SoftwareSerial mySerial(0, 1); // RX, TX

This may be of interest:

Separation of USB and serial communication. On the Leonardo, Leonardo ETH and Micro, the main Serial class refers to the virtual serial driver on the board for connection to your computer over USB. It's not connected to the physical pins 0 and 1 as it is on the Uno and earlier boards. To use the hardware serial port (pins 0 and 1, RX and TX), use Serial1. (See the Serial reference pages for more information.)

From the Arduino Leonardo page.

Datasheet for SiLabs CP2102:

Oh yeah, Rx is plugged into 0 and Tx is plugged into 1.

And is there a problem with using the SoftwareSerialExample sketch as modified?

Instead of this...

#include <SoftwareSerial.h>

SoftwareSerial mySerial(0, 1); // RX, TX

Use this...

#define mySerial Serial1

jski3:
Oh yeah, Rx is plugged into 0 and Tx is plugged into 1.

Isn't that the wrong way round?

On my Leonardo Pin 0 is Rx.

...R

Are you using SoftSerial on pins 0 and 1 or are you using Serial1 on those pins ?

Resolved!

2 things:

  1. download CP210X driver source from SiLabs, make, and install.
  2. I saw 2 possible dev files in /dev/serial/by-id/:
lrwxrwxrwx. 1 root root 13 Mar  6 18:13 usb-Arduino_LLC_Arduino_Leonardo-if00 -> ../../ttyACM0
lrwxrwxrwx. 1 root root 13 Mar  6 18:13 usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB0

I open'ed: /dev//ttyUSB0. WRONG!

Should have open'ed: /dev/ttyACM0.

@jski3, do not cross-post. Threads merged.

My victory lab may have been premature.

The configuration I was working with had both Leonardo's USB plugged into the Fedora box and the CP2102 USB-to-UART Bridge Controller plugged into the Fedora box. That's why I had both:

ls /dev/serial/by-id/

lrwxrwxrwx. 1 root root 13 Mar  6 18:13 usb-Arduino_LLC_Arduino_Leonardo-if00 -> ../../ttyACM0
lrwxrwxrwx. 1 root root 13 Mar  6 18:13 usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB0

That's NOT the configuration I need. I need the CP2102 USB-to-UART Bridge Controller plugged into the Fedora box and Leonardo's USB port plugged into another box in BIOS setup.

When I plug the Leonardo's USB port into another box, I loose /dev/ttyACM0. When I try open'ing then read'ing from /dev/ttyUSB0 I get nothing.

I'm trying a minimalist sketch:

void setup()
{
Serial.begin(9600);
}
 
void loop()
{
   Serial.print("Hello World\n");
   delay(1000);
}

And again, I have RX on 0 and TX on 1 plus GND.

Any questions? Any suggestions?

The statement:

Serial.print("Hello World\n");

in loop() is printing to /dev/ACM0, the USB port. The CP2102 USB-to-UART Bridge Controller connected to pins 0 & 1 accomplishes nothing. If I try read'ing from it using /dev/ttyUSB0 I get nothing.

jski3:
The statement:

Serial.print("Hello World\n");

in loop() is printing to /dev/ACM0, the USB port. The CP2102 USB-to-UART Bridge Controller connected to pins 0 & 1 accomplishes nothing. If I try read'ing from it using /dev/ttyUSB0 I get nothing.

You need

Serial1.print("Hello World\n");

for pins 0 and 1

...R

The attached pic is my current set-up. I tried the code mod you suggested and now neither /dev/ttyUSB0 nor /dev/ttyACM0 are getting anything.

The board next to the Leonardo is the USB 2.0 to TTL UART 6PIN CP2102 Module Serial Converter with its Rx & Tx plugged into pins 0 and 1.

Image from Reply #14 so we don't have to download it. See this Simple Image Upload Guide

...R

Your image reinforces what I said in Replies #7 and #13

However a photo of a pencil drawing that shows the connections with all the pins clearly labelled would be more useful.

...R

My sketch is now:

void setup()
{
Serial.begin(9600);
}
 
void loop()
{
   Serial1.print("Hello World\n");
   delay(1000);
}

And I tried swapping Rx and Tx connectors.

All to no avail !

BTW, the black USB cord goes to a Fedora box and the white USB cord goes to a Raspberry Pi 3 board running Raspbian.

How do you expect to write to Serial1 without a Serial1.begin() statement?

Time to put your brain into gear. :slight_smile:

...R

I did and it works. Didn't notice that at first. Should have responded sooner letting you know. Sorry about that.