In this post, we will talk about the basic setup for raspbery pi. This post assumes the Ubuntu server version is installed.
Our objective is to
- Connect raspbery pi to wifi.
- Make raspbery pi connect to wifi automatically on start up
- Discover the IP address of the raspberry pi.
Connect to wifi
We will set up the wifi with old fashion and follow the insturction in the post Connecting to personal wifi on Ubuntu Server 20.04.
The first step is to set up the interface. Usually we will need wlan0
.
# Check which interfaces you are working with sudo ip link # Example: Set up wlan0 #sudo link set wlan up <--- This may not work. sudo ip link set wlan0 up
The second set step is to configure the wifi connection. We will need wifi network name and wifi password. We will execute the following command, which saves the encrypted confiruation to a wpa_supplicant.conf file.
wpa_passphrase "<Wifi Name>" "<Password>" > /etc/wpa_supplicant/wpa_supplicant.conf
Note that we need sudo
access for the above command but the IO redirection is not always compatible with sudo
. One solution is to execute the command in an interactive shell with sudo access. We can enter the interactive shell using
sudo -s
and then execute the wpa_passphrase
command. After the wifi configuration is saved, we can exit the interactive shell by entering Ctrl+D
.
An alternative is to first redirect the output to a temporary file and then use sudo mv
to copy the file to the wpa_supplicant.conf.
The third step is to enable DHCP by executing
wpa_supplicant -Bc /etc/wpa_supplicant/wpa_supplicant.conf -i <interface> dhclient <interface>
To verify we are connecting to the wifi, we can ping google:
ping -c 5 www.google.com
Connect to wifi automatically on start up
In old Ubuntu version, we can achieve this by adding the commands in the previous section to /etc/rc.local
file. However, Ubuntu 20.04 does not have the rc.local file by default thus we need to create one ourselves.
This section is a copy of the post How to Enable /etc/rc.local with Systemd.
1. Create /etc/systemd/system/rc-local.service file with the following content
[Unit] Description=/etc/rc.local Compatibility ConditionPathExists=/etc/rc.local [Service] Type=forking ExecStart=/etc/rc.local start TimeoutSec=0 StandardOutput=tty RemainAfterExit=yes SysVStartPriority=99 [Install] WantedBy=multi-user.target
2. Create /etc/rc.local file and make it executable by using the following command
sudo chmod +x /etc/rc.local
The /etc/rc.local file should contain the following code. (Here the interface is wlan0).
#!/bin/bash ip link set wlan0 up wpa_supplicant -Bc /etc/wpa_supplicant/wpa_supplicant.conf -i wlan0 dhclient wlan0
3. Enable and start the rc-local service.
sudo systemctl enable rc-local sudo systemctl start rc-local.service sudo systemctl status rc-local.service
Discover the raspberry pi host
An ideal solution would be making raspberry pi send out an email with ip information on start up. However, due to the two-factor verification of gmail, it becomes a little bit tricky to set up an email server on ubuntu server. There are many online posts descriping different solutions to set up a send-only email server. I tried a bunch of them but I'm still not able to set up an email server on my raspberry pi.
Fortunately there is a plan B. The real objective is to get the IP address. We need the IP address mostly because we want to ssh to the raspberry pi from a remote PC. One way to achieve this is to send a broadcast message to the local network and get the hostname. There are a few difficulties with this solution. First, not all machines response to a broadcast message. Second, we need a sort of DNS for local network.
The first problem is not a big deal. We can manully ping a range of IP address. For the second problem, I don't really know how to implement a DNS for a local network but once again our ultimate objective is to discover the IP address assocaited with our raspberry pi and it can be done without knowing/getting the hostname.
One observation is when we ping an IP address and if the host is reachable we will have the MAC address in the output. Therefore, we should be able to identify the raspberry pi from the output of ping
command. To find out the MAC address of raspberry pi, we could execute the ifconfig
command.
Now putting all pieces together, in order to discover the raspberry pi host, we can do the following
- Get the MAC address of the raspberry pi by executin
ifconfig
command. - Ping a range of local IP address and get the results.
- Find the line with the MAC address of the raspberry pi in the ping result and it will contain the IP address of the raspberry pi.
fping
command, which is designed to be used in a script
Here is the sample python code(discover-host.py):
import subprocess
from collections import namedtuple
HostInfo = namedtuple("HostInfo", ["hostname", "mac"])
TARGET_HOST_INFO = [
HostInfo(hostname="robot-ubuntu", mac="<MAC address of Raspberry PI>")
]
if __name__ == "__main__":
macToHostnameMap = {info.mac : info.hostname for info in TARGET_HOST_INFO}
subprocess.run(['fping', '--timeout=200', '-g', '10.0.0.1', '10.0.0.254'])
completedProcess = subprocess.run(['arp', '-a'], capture_output=True)
listOfResult = completedProcess.stdout.decode('UTF-8').split('\n')
isAnyTargetFound = False
for result in listOfResult:
for mac in macToHostnameMap.keys():
if mac in result:
isAnyTargetFound = True
print("[{}] {}".format(macToHostnameMap[mac], result))
if not isAnyTargetFound:
print("Did not find any target result.")
We could remove error message from the outputs as well
alias discoverhost="python3 discover-host.py | grep -v \"is unreachable\" | grep -v\"error\""
----- END -----
©2019 - 2024 all rights reserved