This post should serve as a guide to configure
Raspbian in order to obtain
an interactive terminal capable of executing commands on a Raspberry Pi that is
connected to the computer through a USB port.
Warning: This is an old post with potentially outdated information. Read with
caution.
We will explore two ways to connect a PC to a Raspberry Pi:
The first one is to connect PC and Raspberry Pi Zero through a micro-USB
cable, configure Raspian to treat this connection as an ethernet connection and
finally use SSH.
The second way is to use a USB-UART converter, configure Raspian to transmit a
console through the GPIO pins of serial communication, and finally use
GNU/screen to connect to the tty port
associated with the board.
This guide was developed by performing tests with Raspberry Pi Zero and
Raspberry Pi 3B along with Raspbian Stretch. The computer operating system I
used was Debian 10 Buster.
Connection method 1 - Using a USB cable
For this connection, you only need a micro-USB cable to connect a USB port from
the computer to a USB port on the Raspberry.
On your computer, mount the file system of the microSD card on which you
installed Raspbian. Go to the root of the boot
partition of the mounted
file system. There are three things to do there:
- At the end of the
config.txt
file, insert a new line containing
dtoverlay=dwc2
.
echo dtoverlay=dwc2 >> config.txt
- Open the
cmdline.txt
file. Be careful that the parameters in this file are
single-spaced (ie, line breaks are not used). Insert modules-load=dwc2,g_ether
after rootwait
. If you wish to enable both ethernet and serial connections on
the Raspberry, change g_ether
to g_cdc
.
- Create an empty file called
ssh
with no extension.
Go to the root of the rootfs
partition of the SD and add static IP settings
for the USB network interface.
echo -e "allow-hotplug usb0 \niface usb0 inet static \naddress=192.168.10.254 \nnetmask 255.255.255.0" | sudo tee -a /etc/network/interfaces
The end of the file should look like this:
allow-hotplug usb0
iface usb0 inet static
address 192.168.10.254
netmask 255.255.255.0
Once these steps are complete, the file system can be unmounted and the microSD
card is ready to be inserted into the Raspberry Pi. The next Raspbian boot
process may take a little longer after the changes are made (up to 90 seconds).
Before connecting the Raspberry Pi to the computer, let’s first list the
available network interfaces. This will help us identify which network interface
the Pi will be associated with.
Figure 1. List of network interfaces shown by ifconfig
.
We can see that there are three available network interfaces: enp2s0f0, lo, wlp3s0.
Connect the Raspberry Pi to the computer using a USB cable.
Figure 2. Raspberry Pi and PC connected with a micro-USB cable.
Note that for the Raspberry Pi Zero it is advantageous to use the micro USB port
that has “USB” written next to it. By connecting to this port it is possible to
power and transmit data to the Raspberry Pi simultaneously.
Ensuring PC and Raspberry Pi are on the same network
Now we must make sure that our computer and Raspberry are on the same network.
For this we will list the network interfaces again.
Figure 3. List of network interfaces shown by ifconfig
after connecting the
Raspberry Pi.
Now that the Raspberry Pi is connected you can see that one more network
interface has been created, enp0s29u1u1i1. We can see that it is active (UP) and
that the IP associated with the computer on this interface is 192.168.10.200
(inet 192.168.10.200). This is the desirable state in which PC and Raspberry Pi
are on the same network. If the IP address is not on the same network
(192.168.10) or if no value is displayed for inet
, it will be necessary to
configure the new network interface to assign a new IP address to the PC. In
Debian Buster this can be done in at least two ways:
By editing the network interface settings under ‘Network Connections’.
Figure 4. Editing network configurations through NetworkManager GUI.
It is important to set the IP addressing method to manual and assign an IP
address to the computer that belongs to the same network that you defined in the
/etc/network/interfaces
file of the Raspbian file system. In this post I
defined that the Pi would belong to the network address 192.168.10 (Class C IP
address) so the IP address of the computer must start with 192.168.10 and its ID
must be a number between 0 and 255. For this example, I chose the machine
address within the network to be 200.
Another way to configure the network interface is by manually editing the file
/etc/NetworkManager/system-connections/<interface>.nmconnection
.
sudo vim /etc/NetworkManager/system-connections/<interface>.nmconnection
I leave here an image with the content of my network interface configuration
file for connecting to Raspberry. Note that the connection id “USB-pi”, the
defined IP address, and the addressing method appear.
Figure 5. Changing network configurations through a config file.
If the network interface doesn’t appear with ifconfig
or if you are not sure
about the configuration associated with the network interface, you can try
to get some information with dmesg
.
Connecting with SSH
Having configured the Raspbian and linux network interfaces running on the PC,
it should be possible to connect to the Raspberry Pi using ssh. The more
traditional way of doing this is using the IP address of the device and the user
to connect with.
For example:
If you have avahi-daemon installed
you can also connect by entering the hostname
of your Raspberry Pi. For
example:
Connection method 2 - Using a USB-UART Converter
For this connection you will need some female-female jumpers (wires) and a
USB-UART converter capable of operating at TTL 3.3V (I will discuss more details
later). As some of the settings are the same for USB-ethernet and serial-UART
connection cases, I could just point out some of the steps above but I’ll
rewrite them here for convenience and organization.
On your computer, mount the file system of the microSD card on which you
installed Raspbian. Navigate to the root of the boot
partition of the mounted
file system. There are three things to do here:
- At the end of the
config.txt
file, insert a new line containing
dtoverlay=dwc2
.
echo dtoverlay=dwc2 >> config.txt
Also make sure there is a line containing enable_uart=1
in that file. If it
does not exist or has the value 0, set it to 1.
- Open the
cmdline.txt
file. Be careful that the parameters in this file are
single-spaced (ie, line breaks are not used). Insert modules-load=dwc2,g_serial
after rootwait
. If you wish to enable both ethernet and serial connections on
the Raspberry, change g_serial
to g_cdc
.
Once these steps are complete, the file system can be unmounted and the microSD
card is ready to be inserted into the Raspberry Pi. The next Raspbian boot
process may take a little longer after the changes are made (up to 90 seconds).
Just to make the final settings you will need to connect a keyboard and monitor
to the Raspberry Pi to execute some commands.
Turn on the Raspberry Pi and log in with your username.
- Enable the Raspberry Pi to provide an interactive console over serial by
editing the settings with raspi-config.
Go to Interfacing Options
.
Figure 6. raspi-config tool main screen.
Select Serial
and choose “Yes” to enable console over serial.
Figure 7. raspi-config interfacing options.
- To use the standard serial module, you must also tell the Raspberry Pi to
pass the serial console to it.
sudo systemctl enable getty@ttyAMA0.service
Physical Connection
Since the serial communication GPIO pins on the Raspberry Pi operate at a TTL
logic level of 3.3V, using a USB-UART or USB-TTL converter whose voltages on the
RX and TX pins are greater than 3.3V can damage the Raspberry Pi’s UART
controller! So make sure your converter works at TTL 3.3V by reading the
datasheet or using a multimeter (the voltage between the GND and RX/TX pins must
not exceed 3.6V).
In my experiment I used a USB-UART converter with a WCH CH340G IC that has a
jumper allowing to select which logic level the RX and TX pins should operate.
Figure 8. A USB-UART converter.
In this module, shorting the VCC and 3V3 pins ensures that the TTL logic level 1
will be 3.3V.
Note: Short circuiting the VCC and 5V pins will make the module use TTL 5V which
is used to communicate with various Arduino models. This is especially useful
for programming some Arduino Pro-Mini models.
The GND, RX, TX pins of the USB-UART converter must be connected with the GND,
TX, RX pins of the Raspberry Pi respectively. The physical setup will look like
this:
Figure 9. Raspberry Pi and PC connected with a USB-UART converter.
Accessing the shell
After connecting PC and Raspberry you can run lsusb
command on your computer
to check if a new USB device is recognized by the system.
Figure 10. lsusb
command shows the USB-serial adapter pluged in.
Right on the first line we can see that a USB-Serial adapter has been identified.
Use dmesg
to quickly find out which tty port your Raspberry Pi is associated
with.
Figure 11. dmesg
shows the tty associated with the serial adapter.
In my case, it is on the ttyUSB0 port.
To get a terminal with a shell from the tty file we can use
GNU/screen. You can get it from the
website or from the apt
package manager.
With screen installed, just start it informing the file that should be used.
screen <arquivo tty> [baud rate]
For example:
If you’re denied access to serial devices, try add your user to the dialout
group with sudo usermod -aG dialout $USER
. Reboot the computer for this change
to take effect.
You will see the screen start a new session where the version of Raspbian
running on the Raspberry Pi will appear, the tty file created in it to support
serial communication, and a login prompt. If you get no shell within a few
seconds, try pressing enter a few times and GNU/scree will guess the correct
baud rate.
Figure 12. Connected to the Raspberry Pi with screen.
You may also look for the actual baud rate in the cmdline.txt
file and pass
it to screen:
screen /dev/ttyUSB0 115200
You are now logged into a shell on Raspberry and can run any command from there.
To exit the screen press Ctrl-a \ (Ctrl + a followed by \).
Is there a way to use a male-to-male USB cable?
I tried to make the connection using a male-to-male USB cable connecting a USB
port on the computer to another USB port on the Raspberry Pi 3. According to the
literature, the USB ports on the Raspberry Pi 3 are OTG (On-The-Go) host and, it
seems that a USB device operating in host mode can only communicate with USB
devices operating in device mode and vice versa. The reason for this would be
because the host device is responsible for initiating all communications while
the peripheral device only responds to requests from the host. As the USB ports
of computers normally operate as a host, it is conceivable that both ports try
to initiate some communication but neither of them waits to be notified
asynchronously to respond to a request.
Maybe it would be possible to work around this situation using a USBNET cable
(eg https://www.amazon.com/Belkin-Transfer-Cable-Windows-F4U060/dp/B0093HCIQ0 ),
but I didn’t want to invest time and money in this.
References
Next, I list a series of pages I looked at when writing this post. They may be
useful for troubleshooting.
Description of available connection modules available for Raspbian
https://gist.github.com/gbaman/50b6cca61dd1c3f88f41
USB-ethernet connection
https://www.thepolyglotdeveloper.com/2016/06/connect-raspberry-pi-zero-usb-cable-ssh/
https://gist.github.com/gbaman/975e2db164b3ca2b51ae11e45e8fd40a
https://www.youtube.com/watch?v=MJ084wtjiWM
Network Interface Settings in Debian
https://wiki.debian.org/NetworkConfiguration
Debug USB OTG g_serial gadget
https://raspberrypi.stackexchange.com/questions/67907/debugging-usb-otg-serial-on-the-pi-zero-w
https://github.com/raspberrypi/linux/pull/1239
GPIO-UART connection
http://www.embeddedforu.com/embedded-linux/how-to-connect-raspberry-pi-uart-to-a-computer/
https://www.raspberrypi.org/documentation/configuration/uart.md
https://www.instructables.com/id/Read-and-write-from-serial-port-with-Raspberry-Pi/
https://elinux.org/RPi_Serial_Connection
Raspberry Pi pinout scheme
https://www.raspberrypi.org/documentation/usage/gpio/README.md
https://pinout.xyz/#
Connecting to a serial port with GNU/screen
https://unix.stackexchange.com/questions/22545/how-to-connect-to-a-serial-port-as-simple-as-using-ssh
https://askubuntu.com/questions/40959/how-do-i-connect-to-tty-com-dev-ttyusb0
Raspberry Pi USB Ports
https://www.raspberrypi.org/documentation/hardware/raspberrypi/usb/README.md
https://www.raspberrypi.org/forums/viewtopic.php?t=223573
USBNET
https://www.raspberrypi.org/forums/viewtopic.php?f=36&t=131042
http://www.linux-usb.org/usbnet/