What does if __name__ == “__main__”: do?

A module’s __name__

Every module has a name and statements in a module can find out the name of its module. This is especially handy in one particular situation – As mentioned previously, when a module is imported for the first time, the main block in that module is run. What if we want to run the block only if the program was used by itself and not when it was imported from another module? This can be achieved using the __name__ attribute of the module.

Using a module’s __name__

#!/usr/bin/python

# Filename: using_name.py

if __name__ == '__main__':
    print 'This program is being run by itself'
else:
    print 'I am being imported from another module'

Output

                
$ python using_name.py
This program is being run by itself

$ python
>>> import using_name
I am being imported from another module
>>>

How It Works

Every Python module has it’s __name__ defined and if this is '__main__', it implies that the module is being run standalone by the user and we can do corresponding appropriate actions.


Question:

What does the if __name__ == "__main__": do?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
while 1:
lock
.acquire()
time
.sleep(sleeptime)
lock
.release()
time
.sleep(sleeptime)
if __name__ == "__main__":
lock
= thread.allocate_lock()
thread
.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread
.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

Answer:

When the Python interpreter reads a source file, it executes all of the code found in it.

Before executing the code, it will define a few special variables. For example, if the python interpreter is running that module (the source file) as the main program, it sets the special __name__ variable to have a value "__main__". If this file is being imported from another module, __name__ will be set to the module’s name.

In the case of your script, let’s assume that it’s executing as the main function, e.g. you said something like

python threading_example.py

on the command line. After setting up the special variables, it will execute the import statement and load those modules. It will then evaluate the def block, creating a function object and creating a variable called myfunction that points to the function object. It will then read the if statement and see that __name__ does equal "__main__", so it will execute the block shown there.

One reason for doing this is that sometimes you write a module (a .py file) where it can be executed directly. Alternatively, it can also be imported and used in another module. By doing the main check, you can have that code only execute when you want to run the module as a program and not have it execute when someone just wants to import your module and call your functions themselves.

Advertisements

Samsung announces Connect Tag tracker that uses cellular IoT tech to help you find people and things

There is no shortage of little portable tracker devices that you can attach to your keys or your dog to ensure you never lose the things that matter most. But Samsung has today announced the Samsung Connect Tag, one of the first mobile consumer products that uses the fledgling narrowband IoT (NB-IoT) standard to connect devices.

For the uninitiated, NB-IoT licenses small amounts of LTE cellular spectrum to carry data for low-bandwidth devices. NB-IoT offers many benefits, including strong coverage, greater power efficiency (to preserve batteries), support for many devices, and relatively low operational costs. As its name suggests, it was very much designed with the internet of things in mind, and moving forward it will likely be used to connect myriad IoT contraptions, from smart trash cans to parking bay sensors.

At just 4.21 centimeters wide and 1.19 centimeters thick, the Samsung Connect Tag is fairly small and sports an embedded SIM (eSIM), which is basically a non-removable, programmable “virtual” SIM that consumes less space and doesn’t require the user to install a physical card.

As with similar trackers on the market, the device can be put to any number of uses, such as finding lost keys or giving parents peace of mind when their kid is out and about. The Connect Tag works with GPS, Wi-Fi-based positioning (WPS), and Cell ID (CID) to identify location data indoors and outdoors.

Above: Samsung Connect Tag

Building on Samsung’s push into the broader IoT realm, the Connect Tag works in conjunction with Samsung’s SmartThings Hub and the Samsung Connect mobile app so users can control and configure things remotely, while being able to integrate the tracker with other connected devices. For example, a user could set up a geo-fence zone for their home so that lights turn on automatically when the Connect Tag comes within a pre-defined perimeter. Alternatively, it could be used to notify a parent when their child arrives at school.

Though similar features and functionality already exist in other products, Samsung is touting the NB-IoT element as a key selling point. While it offers cellular connectivity for constantly tracking a specific person or product, it also promises “up to” seven days on a single charge, which is pretty good. However, we will reserve judgement until we can test one of these devices out for ourselves.

A number of companies have raised big VC funding for mobile tracking contraptions, including San Mateo-based Tile and Santa Barbara’s TrackR. Earlier this year, New York-headquartered Lynq announced a $2 million round of funding for a tracker that lets you find anyone in a radius of up to five miles. This tracker sidesteps Bluetooth, maps, Wi-Fi, and cell networks with a decentralized peer-to-peer (P2P) network that uses a mix of radio frequencies, a custom antenna, and a long-range low-powered chip.

Put simply, there is big demand for tracker devices, and it’s a market that Samsung is now looking to infiltrate. The company is debuting the Connect Tag at its developer conference in San Francisco later this week. But the device will first go on sale in Korea before expanding to “select countries” at a later date. Samsung hasn’t given any indication of price or launch dates.

Cellular NarrowBand IOT

NarrowBand IoT (NB-IoT) is a Low Power Wide Area Network (LPWAN) radio technology standard developed to enable a wide range of devices and services to be connected using cellular telecommunications bands. NB-IoT is a narrowband radio technology designed for the Internet of Things (IoT) and is one of a range of Mobile IoT (MIoT) technologies standardized by the 3rd Generation Partnership Project (3GPP). Other 3GPP IoT technologies include eMTC (enhanced Machine-Type Communication) and EC-GSM-IoT. The NB-IoT specification was frozen at Release 13 of the 3GPP specification (LTE-Advanced Pro), in June 2016.

NB-IoT focuses specifically on indoor coverage, low cost, long battery life, and enabling a large number of connected devices. The NB-IoT technology is deployed “in-band” in spectrum allocated to Long Term Evolution (LTE) – using resource blocks within a normal LTE carrier, or in the unused resource blocks within a LTE carrier’s guard-band – or “standalone” for deployments in dedicated spectrum. It is also suitable for the re-farming of GSM spectrum.

LTE Cat 1 LTE Cat 0 LTE Cat M1(eMTC) LTE Cat NB1(NB-IoT) EC-GSM-IoT
3GPP Release Release 8 Release 12 Release 13 Release 13 Release 13
Downlink Peak Rate 10 Mbit/s 1 Mbit/s 1 Mbit/s 250 kbit/s 474 kbit/s (EDGE)2 Mbit/s (EGPRS2B)
Uplink Peak Rate 5 Mbit/s 1 Mbit/s 1 Mbit/s 250 kbit/s (multi-tone)20 kbit/s (single-tone) 474 kbit/s (EDGE)2 Mbit/s (EGPRS2B)
Latency 50-100ms not deployed 10ms-15ms 1.6s-10s 700ms-2s
Number of Antennas 2 1 1 1 1-2
Duplex Mode Full Duplex Full or Half Duplex Full or Half Duplex Half Duplex Half Duplex
Device Receive Bandwidth 1.08 – 18 MHz 1.08 – 18 MHz 1.08 MHz 180 kHz 200 kHz
Receiver Chains 2 (MIMO) 1 (SISO) 1 (SISO) 1 (SISO) 1-2
Device Transmit Power 23 dBm 23 dBm 20 / 23 dBm 20 / 23 dBm 23 / 33 dBm

Sources:

  • Preliminary specification (Source: 3GPP)
  • 3GPP TS45.001

See also

Enabling Simultaneous AP and Managed Mode WiFi on Raspberry Pi Zero W

Personal note: Running both an access point and a client configuration on the same network adapter (i.e., simultaneous Client/AP mode) requires support for so-called virtual interfaces. Whether a certain Wifi hardware and driver combo supports virtual interfaces and in which configurations can be found out by looking at iw list output (look for AP and managed together under valid interface combinations).

People have said Atheros based wifi adapter -(e.g., TP-LINK TL-WN722N) is capable of doing such. The on-board wifi chip on Raspberry Pi isn’t, as I verified. Below is the actual output.

///////////////////////////////////////////////////////////////////////////////////////

valid interface combinations:
* #{ managed } <= 1, #{ P2P-device } <= 1, #{ P2P-client, P2P-GO } <= 1,
total <= 3, #channels <= 1
* #{ managed } <= 1, #{ AP } <= 1, #{ P2P-client } <= 1, #{ P2P-device } <= 1,
total <= 4, #channels <= 1

///////////////////////////////////////////////////////////////////////////////////////

After looking around a bit online, I found several people who claimed to have gotten this working, as well as posts saying it should work, based on the chipset. Despite my best efforts, I was unable to get any of those tutorials to work reliably on their own. By combining some information garnered from each one, along with some trial and error, I was finally able to get AP/Manged mode working, as described below.

Prerequisites

This tutorial assumes you’ve already created a bootable MicroSD card running the latest Raspbian Stretch image and have some way of accessing Linux, whether via serial interface, or a monitor and keyboard. If you haven’t, a couple of great resources I found online are:

  • Raspberry Pi Zero W “headless” Setup – This great tutorial walks you through getting WiFi client mode enabled on your RPi Zero W, without need for an attached monitor or keyboard. You will need a way to modify the contents of the MicroSD card’s filesystem, such as a Linux machine, Chromebook with crouton, or VM. There are also ways to do this from Windows, but I’ll leave that as an exercise for the reader.
  • Raspberry Pi Zero OTG Mode – Another awesome tutorial, via GitHub gist, which explains how to enable OTG / USB Gadget mode on the RPi Zero / Zero W. OTG mode lets you both power and communicate with the RPi Zero W as a virtual serial device, ethernet device, or mass storage device, among other things, with nothing more than a standard (read: non-OTG) USB cable. I used this to directly access the Raspbian Linux terminal via USB while trying to tweak the WiFi settings so that I wouldn’t drop my ssh session from headless mode.

Adding Udev Rule To Add A Virtual AP Device At Boot Time

Before we can operate our access point, we need a device allocated for it, similar to how systemd allocates a wlan0 device at boot time. On the build of Raspbian Stretch I’m using, only wlan0 is available automatically. We create a file caled /etc/udev/rules.d/70-persistent-net.rules which contains the following:

SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="b8:27:eb:ff:ff:ff", KERNEL=="phy0", \
  RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
  RUN+="/bin/ip link set ap0 address b8:27:eb:ff:ff:ff"

Note that you must replace both MAC addresses above with that of your own RPi. You can find yours in various ways, such as from your router’s client list, or from the RPi’s command line via iw dev:

pi@raspberrypi:~$ iw dev
phy#0
        Unnamed/non-netdev interface
                wdev 0x4
                addr ba:27:eb:07:28:1f
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 2
                wdev 0x1
                addr b8:27:eb:ff:ff:ff
                ssid <YOUR HOME SSID> 
                type managed
                channel 6 (2437 MHz), width: 20 MHz, center1: 2437 MHz
                txpower 31.00 dBm

A number of tutorials I found claimed that the address for the virtual AP must be different from the primary MAC address. I found there to be no difference in behavior, but you should be able to change the last byte, for example, to give your client and AP different MACs.

The device we created above is called ap0. We will refer to this elsewhere, so if you decide to change the name, make sure to use the new name everywhere else I reference it, or things won’t work correctly.

Installing Dnsmasq and Hostapd

  • Dnsmasq – This program has extensive features, but for our purposes we are using it as a DHCP server for our WiFi AP.
  • Hostapd – This program defines our AP’s physical operation based on driver configuration.

Installing these is an easy affair:

$ sudo apt-get install dnsmasq hostapd

Wait awhile, and this process should complete. The install process may automatically start the dnsmasq.service in systemd right after installation and it will probably fail, since ap0 does not exist until we reboot. Disregard this for now.

Next, we need to modify 3 files. First we modify /etc/dnsmasq.conf by adding the following lines at the end of the file:

interface=lo,ap0
no-dhcp-interface=lo,wlan0
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=192.168.10.50,192.168.10.150,12h

Once again, notice we reference ap0 above, so use your device name here if you changed it earlier. I’ve added Google’s DNS server IP here (8.8.8.8) but feel free to use one from your router/ISP/or whatever. I’ve also made the assumption that our DHCP server will give out addresses on the 192.168.10.0/24 subnet, ranging from .50 to .150. You can substiute your own subnet here, but be sure to remember it for later, as it should match the static IP we assign your AP. The 12 hour lease time can also be arbitrarily changed to suit your needs.

Next, we need to modify the file at /etc/hostapd/hostapd.conf. I found many different parameters that can go in here, but this is what worked for me. Feel free to experiment further by poking around online. Lets do this for now:

ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=YourApNameHere
hw_mode=g
channel=11
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=YourPassPhraseHere
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP

A couple things to note here:

  1. Replace YourApNameHere and YourPassPhraseHere with the SSID and Passphrase you wish to use.
  2. I read multiple sources claiming that the channel you use here must match the channel that your wlan0 iterface is using for its WiFi connection, as reported by iw dev. In my testing, it looks like the RPi’s AP will dynamically change channels to match whatever channel the wlan0 interface is currently using. I watched this happen in real time by rebooting the WiFi AP the RPi was using, forcing it to roam and switch to another AP in my house. In the process, wlan0 switched from channel 11 to channel 6, and ap0 did the same, without losing connectivity.

Finally, we modify /etc/default/hostapd like so:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

This tells the hostpad daemon to use our new conf file. (To be honest, I’m not sure if this matters since we will be launching hostapd manually and pointing to the proper config file, but it shouldn’t hurt anything.)

Modify Our Interfaces File

Next, we need to define our WiFi network interfaces, both for our managed access (wlan0) and for our access point (ap0). We will also use wpa_supplicant to assist with connecting to WPA-encrypted WiFi networks. If you followed the “headless” bring-up tutorial I mentioned in the prereqs, you will have already touched both of the following files and configured wlan0 as required. In that case, we’ll be adding a static IP definition for ap0. First, we modify /etc/wpa_supplicant/wpa_supplicant.conf as so:

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="YourSSID1"
    psk="YourPassphrase1"
    id_str="AP1"
}

network={
    ssid="YourSSID2"
    psk="YourPassphrase2"
    id_str="AP2"
}

Again, you should replace the SSIDs and Passphrases above with your own. You aren’t required to name multiple SSIDs here, but if you add more, the RPi can roam between networks if configured correctly, as we will do below. The id_str field can be used as a quick reference name in our interfaces file. You should also change the country code to whatever is appropriate for your region.

Next, we modify /etc/network/interfaces to support our new AP:

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
auto ap0
auto wlan0
iface lo inet loopback

allow-hotplug ap0
iface ap0 inet static
    address 192.168.10.1
    netmask 255.255.255.0
    hostapd /etc/hostapd/hostapd.conf

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface AP1 inet dhcp
iface AP2 inet dhcp

As you can see, we want both ap0 and wlan0 to start up automatically, with ap0 defined to have a static IP of 192.168.10.1 on the 192.168.10.0/24 subnet. Recall, the DHCP address range we defined in /etc/dnsmasq.conf matched this subnet. Adjust accordingly if you made changes. We also reference our hostapd config file here, to direct the AP configuration for ap0.

For wlan0, we start it using manual mode and point it to our /etc/wpa_supplicant/wpa_supplicant.conf file for our WiFi network definitions. The wpa-roam designator will allow the interface to move freely between our defined networks. Finally, the last two lines use our friendly names from wpa_supplicant.conf to refer to our available networks, and indicate this interface should use DHCP supplied by those APs to assign an address to wlan0. Please note the order here: ap0 must come up before wlan0, or they won’t both work at the same time.

We’re Done! Or Are We…

At this point, I expect everything to work after a reboot. Instead, I end up with wlan0 UP and ap0 DOWN (or vice-versa) when checking via ip addr, and dmesg indicates some errors in the Broadcom driver. After some tinkering, I discovered the following sequence of commands after a reboot would get both interfaces up and working simultaneously, like we wanted all along:

$ sudo ifdown --force wlan0
$ sudo ifdown --force ap0
$ sudo ifup ap0
$ sudo ifup wlan0

I had to add --force because sometimes hostapd would complain about having a lock on wlan0 and fail to proceed, so it ensures we get what we want. After bringing down both interfaces, again, with ap0 going first, followed by wlan0, they should both come up:

pi@raspberrypi:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:ff:ff:ff brd ff:ff:ff:ff:ff:ff
    inet 192.168.43.37/24 brd 192.168.43.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fede:3a79/64 scope link
       valid_lft forever preferred_lft forever
3: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:ff:ff:ff brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.1/24 brd 192.168.10.255 scope global ap0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fede:3a79/64 scope link
       valid_lft forever preferred_lft forever

Great! But what about bridging traffic between my AP and client sides to allow a device to access the internet through my RPi? Let’s do that:

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.0/24 -j MASQUERADE
$ sudo systemctl restart dnsmasq

Here, we enable ip forwarding to allow packets to be forwarded between interfaces, and we add a postrouting rule to IP tables which routes all packets from the AP-side interface to the client-side interface (where MASQUERADE is necessary, since the IP is dynamic and undefined until wlan0 connects to an AP). Finally, we restart dnsmasq for good measure, since we previously brought down ap0 with ifdown.

At this point, we should be able to connect a device to our Raspberry Pi Zero W’s AP SSID, while we also have our RPi connect to another access point for internet access, and we should be able to access the internet from that device through our RPi. Only one thing left to do…

Automate The Workaround

Try as I might to debug the issues I was having before manaully reseting the interfaces, I was unable to get the RPi to simply boot up working correctly. So, I decided to script the steps to “fix” everything and set them to run as a root cron job with a 30s delay… (Yes, I know this is horrible practice, but I’m open to better suggestions.) I intially tried setting up a systemd service to call my script instead of cron with a delay, but it didn’t seem to work or ran at the wrong time, requiring manual intervention.

Here’s the script in it’s entirety:

pi@raspberrypi:~$ cat ./start-ap-managed-wifi.sh
#!/bin/bash
sleep 30
sudo ifdown --force wlan0 && sudo ifdown --force ap0 && sudo ifup ap0 && sudo ifup wlan0
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 ! -d 192.168.10.0/24 -j MASQUERADE
sudo systemctl restart dnsmasq

I simply left the file in my default “pi” user’s home directory, but you can move it someplace more appropriate, such as /sbin. I then added a cron job like so:

$ sudo crontab -e

And in there I added the line:

@reboot /home/pi/start-ap-managed-wifi.sh

This causes the script to run at every reboot. In testing, I foud the RPi Zero W boots in under 20s. Systemd runs the cron service somewhere in that range of time, which eventually runs the script above. To be safe, you can change the 30s delay to something longer, but I found this to be pretty reliable.

Now, after every reboot, even though ap0 and wlan0 don’t initally play well together, the cron job kicks off my script after 30s and magically fixes everything. We have AP and Managed mode running at the same time, and we’re bridging traffic between the interfaces to allow for internet sharing through the Raspberry Pi Zero W.

Special Thanks

The following links were pretty instrumental in getting things moving in the right direction, so please check them out:

Please comment below if this helped you, or if you have any suggestions for improvements!

Personal note: You should disable dhcpcd at boot by running
sudo update-rc.d dhcpcd disable
However, the ethernet would be disabled as well at boot. This has been tested on Raspberry Pi 3 model B.

 

A good Express JS crash course

 

Express.js, or simply Express, is a web application framework for Node.js, released as free and open-source software under the MIT License. It is designed for building web applications and APIs. It is in fact the standard server framework for Node.js.

The original author, TJ Holowaychuk, described it as a Sinatra-inspired server, meaning that it is relatively minimal with many features available as plugins. Express is the backend part of the MEAN stack, together with MongoDB database and AngularJS frontend framework.

 

Raspberry Pi Serial Connection

Source: https://elinux.org/RPi_Serial_Connection

The serial port is a low-level way to send data between the Raspberry Pi and another computer system. There are two main ways in which it can be used:

  • Connecting to a PC to allow access to the Linux console. This can help to fix problems during boot, or to log in to the Raspberry Pi if the video and network are not available.
  • Connecting to a microcontroller or other peripheral which has a serial interface. This can be useful if you want the Raspberry Pi to control another device.

Contents

Connections and signal levels

https://i5.walmartimages.com/asr/9bc0ebe4-4821-444b-ba74-069620130c7e_1.8c186df8e8aabe5b085c93fd56bf6e24.jpeg?odnHeight=450&odnWidth=450&odnBg=FFFFFF

The Raspberry Pi serial port consists of two signals (a ‘transmit’ signal, TxD and a ‘receive’ signal RxD) made available on the GPIO header. To connect to another serial device, you connect the ‘transmit’ of one to the ‘receive’ of the other, and vice versa. You will also need to connect the Ground pins of the two devices together.

The Broadcom chip at the heart of the Raspberry Pi uses 0 and 3.3 V logic levels, not the +/-12 V used by RS-232 serial ports found on some older PCs. If you wish to connect one of these, you need a board or adapter to convert the signal levels. See this tutorial for one example on how to build a 3.3 V to RS-232 level converter with a breadboard, a MAX3232CPE IC and five 0.1 µF capacitors.

If you wish to connect your Raspberry Pi to a PC with a USB port, the simplest option is to use a USB-to-serial cable which uses 3.3 V logic levels (e.g. the Adafruit 954 cable, the FTDI TTL-232R-RPI cable, or the Debug Buddy ultimate serial port). These can be simply plugged in directly to the GPIO header (see illustration).

If you wish to connect to a peripheral which has 0/5 V signals, you should ideally have a circuit to convert between the voltage levels. See this tutorial for an example using a ready-made level shifter module. Other circuits for level shifting are shown at RPi_GPIO_Interface_Circuits#Level_Shifters. The Debug Buddy ultimate serial port can also be configured for 0/5 V signals.

NOTE FOR RASPBERRY PI 3: The Raspberry pi 3 has changed things a bit and you might need to add the option enable_uart=1 at the end of /boot/config.txt (see this post by a Pi Engineer)

Connection to a PC

You can connect the Raspberry Pi to a PC using a USB-serial cable, or (if it has an RS-232 port) a level-converter circuit – see above for details. When this is done, you will need to set up a terminal emulator program on your PC as described below.

Console serial parameters

The following parameters are needed to connect to the Raspberry Pi console, and apply on both Linux and Windows.

  • Speed (baud rate): 115200
  • Bits: 8
  • Parity: None
  • Stop Bits: 1
  • Flow Control: None

Linux terminal set up

If your PC is running Linux, you will need to know the port name of its serial port:

  • Built-in (standard) Serial Port: the Linux standard is /dev/ttyS0, /dev/ttyS1, and so on
  • USB Serial Port Adapter: /dev/ttyUSB0, /dev/ttyUSB1, and so on.
    • Some types of USB serial adapter may appear as /dev/ttyACM0

You will need to be a member of the dialout group to access this port (for later releases the required group is tty). You can check which is needed with:

ls -l /dev/ttyUSB0

and you will see something like “crw-rw—-T 1 root dialout …”, c means character device, and root can ‘read,write’ and the group dialout can ‘read,write’ to the port and everyone else cannot access it.

To find out if you, the current user, is in the group dialout, use the command:

id

If you do not see dialout listed, add yourself with the command

sudo usermod -a -G dialout username

You then have a choice of terminal emulation programs:

  • Super Easy Way Using GNU Screen

Enter the command below into a terminal window

 screen port_name 115200

To exit GNU screen, type Control-A k.

  • Super Easy Way Using Minicom

Run Minicom with the following parameters:

minicom -b 115200 -o -D Port_Name

You can exit Minicom with Control-A x

Note: If you haven’t configured minicom before (i.e: first use after installation), or if you find that your keyboard key presses are not sent to the RPi, you should make sure Hardware Flow Control is disabled. See Tedious Old-Fashioned Way Using Minicom to configure minicom.

  • Tedious Old-Fashioned Way Using Minicom

Another method to setup minicom is described in the Tincantools Minicom Tutorial

  • GUI method with GtkTerm

Start GtkTerm, select Configuration->Port and enter the values above in the labeled fields.

Network connection with the point-to-point protocol (ppp)

The easiest way to set up a network connection between your Raspberry Pi and another computer is with an Ethernet cable. If this is not possible, as is the case for the Raspberry Pi Model A, you can set up a connection over the serial cable. This uses the Point-to-point Protocol (PPP). A network connection running over a serial cable can be very useful for copying files onto the Raspberry Pi.

Step 1: Log in to the Raspberry Pi over the serial cable and run the Point-to-Point Protocol Daemon:

 sudo pppd noauth

Some garbage will start appearing in the terminal. This is the cue to quit your terminal program and proceed to step two.

Step 2: On your local computer, start the Point-to-Point protocol. On a Linux or Mac computer you can do this by typing:

 sudo pppd noauth proxyarp /dev/tty.usbserial-FTGCC2MV 115200 10.0.0.1:10.0.0.2 passive local maxfail 0 nocrtscts xonxoff

replacing /dev/tty.usbserial-FTGCC2MV with the name of your serial port. In the above line, 115200 is the baud rate of the connection, 10.0.0.1 is the local internet protocol (IP) address, the address you want your computer to have. 10.0.0.2 is the remote IP address, it is the address that the Raspberry Pi will have.

Test the connection:

 ping 10.0.0.2

Virtual connection to the LAN

Instead of 10.0.0.0/8 you could as well use normal 192.168.0.0/16 addresses; the first address must be the real address of the local (serving) system. You can chose the second address; it must not yet be assigned on the LAN (and be outside the DHCP range). The advantage is that the system connected to the serial line will appear as if it is directly connected to the LAN (arp protocol).

You must enable routing on the system directly connected to the LAN for other systems to access the system connected to the serial line:

sudo sysctl -w net.ipv4.ip_forward=1

On the guest system connected via the serial cable you must set the default route pointing to the serving system, e.g.

sudo route add default gateway 192.168.1.21

You should also configure /etc/resolv.conf if you want to use DNS.

Windows terminal set-up

Users of Windows Vista or later will need to download a terminal program, for instance PuTTY, or TeraTerm. Users of Windows XP and below can choose between using PuTTY and the built-in Hyperterminal.

PuTTY users simply need to choose ‘serial’, select the correct COM port and set the speed, as shown in the dialog below.

Putty-settings.png

If you are unsure of the COM port, run [Device Manager] and look under ‘Ports’. USB-attached serial adapters should have the name of the adapter shown (the Adafruit cable comes up as ‘Prolific USB-to_Serial Comm Port’.

Boot messages

If your connection is set up correctly, when the Raspberry Pi is booted you should see many messages as the system comes up:

Uncompressing Linux... done, booting the kernel.
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.2.27+ (dc4@dc4-arm-01) (gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08) ) #250 PREEMPT Thu Oct 18 19:03:02 BST 2012
[    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine: BCM2708
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 113792
[    0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708.boardrev=0xf bcm2708.serial=0xcc5c4b6d smsc95xx.macaddr=B8:27:EB:5C:4B:6D sdhci-bcm2708.emmc_clock_freq=100000000 vc_mem.mem_base=0x1c000000 vc_mem.mem_size=0x20000000  dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

and so on. Eventually, you should see a login prompt:

Debian GNU/Linux Wheezy/sid raspi2 ttyAMA0

raspi2 login:

You can then log in as you would with a keyboard and screen.

Unwanted serial garbage input

Note that on older software by accident the internal pullups of the RxD GPIO pins were not enabled, this could lead to lots of serial garbage being picked up if the GPIO pin was touched, or even if a finger was nearby. In extreme case this could lead to kernel warnings and other problems.

Connection to a microcontroller or other peripheral

H/W considerations

If your microcontroller or peripheral works with 5V logic levels, level conversion is necessary – see ‘Connecting to a PC’ for details.

If your microcontroller or peripheral works with 3.3V logic levels then you can connect its TxD, RxD signals directly to the RxD and TxD pins of the Raspberry. However it’s probably a good idea to connect the signals with a 2.2 kΩ resistors in series. This will prevent damage if two outputs are accidentally connected together (e.g. if you connect TxD with TxD or if a GPIO input pin is accidentally programmed as output).

S/W: Preventing Linux from using the serial port

By default Linux will grab the serial port and use it as a terminal. If you want to use it for other purposes you must prevent this. Here are the methods you can use:

Method 1, raspi-config (easiest, try this first)

Run sudo raspi-config and check if it has the option advanced options -> serial. If it has, set it to disabled and you’re done.

Method 2, using an existing script (easy)

There’s a nice little script to automate the steps bellow.

Method 3, manual configuration (complex)

If neither raspi-config nor the script works for you then follow the hard way.

NOTE FOR RASPBERRY PI 3: The Raspberry pi 3 has changed things around a bit: ttyAMA0 now refers to the serial port that is connected to the bluetooth. The old serial port is now called ttyS0. So if you have an RPI3, everywhere you see “ttyAMA0” below, you should read “ttyS0”.

The Broadcom UART appears as /dev/ttyAMA0 under Linux. There are several minor things in the way if you want to have dedicated control of the serial port on a Raspberry Pi.

  • Firstly, the kernel will use the port as controlled by kernel command line contained in /boot/cmdline.txt. The file will look something like this:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

The console keyword outputs messages during boot, and the kgdboc keyword enables kernel debugging. You will need to remove all references to ttyAMA0. So, for the example above /boot/cmdline.txt, should contain:

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

You must be root to edit this (e.g. use sudo nano /boot/cmdline.txt). Be careful doing this, as a faulty command line can prevent the system booting.

  • Secondly, after booting, a login prompt appears on the serial port. This is controlled by the following lines in /etc/inittab:
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

You will need to edit this file to comment out the second line, i.e.

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Finally you will need to reboot the Raspberry Pi for the new settings to take effect. Once this is done, you can use /dev/ttyAMA0 like any normal Linux serial port, and you won’t get any unwanted traffic confusing the attached devices.

The above instructions have been verified on Raspbian ‘Wheezy’; other distributions may be set up differently. To double-check, use

cat /proc/cmdline

to show the current kernel command line, and

ps aux | grep ttyAMA0

to search for getty processes using the serial port.

A tutorial on accessing the Raspberry Pi’s serial port from Python is available at Serial_port_programming.

Handshaking lines

You can have the RTS0 signal on GPIO 17 (P1-11) or GPIO 31 (P5-06) if you set them to ALT function 3. Likewise, the CTS0 is available on GPIO 30 (P5-05), if it is set to ALT function 3. You can control the settings of I/O pins with gpio_setfunc.

Glitch when opening serial port

When the serial port is opened the voltage on TXD pulses negative for approximately 32 µs (regardless of the baud rate). This pulse may be interpreted as a transmission by a device connected to the TXD pin, which could have unintended effects. An error tolerant communication protocol should be used to avoid problems this glitch could cause. Another method for avoiding problems is to use a GPIO pin to implement the RTS signal, and to have the connected device ignore all data on TXD until RTS is asserted. If the connected device is susceptible to the glitch and cannot be modified, it is sometimes possible to obtain correct operation by opening the serial port in advance of initiating transmission. This can be done in the shell with the sleep program:

sleep infinity >/dev/ttyAMA0 &

In a shell script, the following commands may be used to kill the sleep process once serial transmission is complete.

sleep infinity >/dev/ttyAMA0 &
sleep_pid=$!
disown $sleep_pid # this is required to prevent an error message when sleep is terminated
# Use serial port here
kill $sleep_pid

Set up WiFi through the command line terminal on Raspberry Pi

This method is suitable if you don’t have access to the graphical user interface normally used to set up WiFi on the Raspberry Pi. It is particularly suitable for use with a serial console cable if you don’t have access to a screen or wired Ethernet network. Note also that no additional software is required; everything you need is already included on the Raspberry Pi.

Getting WiFi network details

To scan for WiFi networks, use the command sudo iwlist wlan0 scan. This will list all available WiFi networks, along with other useful information. Look out for:

  1. ‘ESSID:”testing”‘ is the name of the WiFi network.
  2. ‘IE: IEEE 802.11i/WPA2 Version 1’ is the authentication used. In this case it’s WPA2, the newer and more secure wireless standard which replaces WPA. This guide should work for WPA or WPA2, but may not work for WPA2 enterprise. For WEP hex keys, see the last example here. You’ll also need the password for the wireless network. For most home routers, this is found on a sticker on the back of the router. The ESSID (ssid) for the examples below is testing and the password (psk) is testingPassword.

Adding the network details to the Raspberry Pi

Open the wpa-supplicant configuration file in nano:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Go to the bottom of the file and add the following:

network={
    ssid="testing"
    psk="testingPassword"
}

The password can be configured either as the ASCII representation, in quotes as per the example above, or as a pre-encrypted 32 byte hexadecimal number. You can use the wpa_passphrase utility to generate an encrypted PSK. This takes the SSID and the password, and generates the encrypted PSK. With the example from above, you can generate the PSK with wpa_passphrase "testing" "testingPassword". The output is as follows.

  network={
      ssid="testing"
      #psk="testingPassword"
      psk=131e1e221f6e06e3911a2d11ff2fac9182665c004de85300f9cac208a6a80531
  }

Note that the plain text version of the code is present, but commented out. You should delete this line from the final wpa_supplicant file for extra security.

The wpa_passphrase tool requires a password with between 8 and 63 characters. For more complex passphrases you can extract the content of a text file and use it as input for wpa_passphrase, if the password is stored as plain text inside a file somewhere, by calling wpa_passphrase "testing" < file_where_password_is_stored. For extra security, you should delete the file_where_password_is_stored afterwards, so there is no plain text copy of the original password on the system.

If you are using the wpa_passphrase encrypted PSK you can either copy and paste the encrypted PSK into the wpa_supplicant.confg file, or redirect the tools output to your configuration file by calling wpa_passphrase "testing" "testingPassword" >> /etc/wpa_supplicant/wpa_supplicant.conf. Note that this requires you to change to root (by executing sudo su), or you can use wpa_passphrase "testing" "testingPassword" | sudo tee -a /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null, which will append the passphrase without having to change to root. Both methods provide the necessary administrative privileges to change the file. Lastly, make sure you use >>, or use -a with tee, (both can be used to append text to an existing file) since >, or omitting -a when using tee, will erase all contents and then append the output to the specified file. Note that the redirection to /dev/null at the end of the second form simply prevents tee from also outputting to the screen (standard output).

Now save the file by pressing Ctrl+X, then Y, then finally press Enter.

Reconfigure the interface with wpa_cli -i wlan0 reconfigure.

You can verify whether it has successfully connected using ifconfig wlan0. If the inet addr field has an address beside it, the Raspberry Pi has connected to the network. If not, check that your password and ESSID are correct.

Unsecured Networks

If the network you are connecting to does not use a password, the wpa_supplicant entry for the network will need to include the correct key_mgmt entry. e.g.

network={
    ssid="testing"
    key_mgmt=NONE
}

Hidden Networks

If you are using a hidden network, an extra option in the wpa_supplicant file, scan_ssid, may help connection.

network={
    ssid="yourHiddenSSID"
    scan_ssid=1
    psk="Your_wifi_password"
}

You can verify whether it has successfully connected using ifconfig wlan0. If the inet addr field has an address beside it, the Raspberry Pi has connected to the network. If not, check your password and ESSID are correct.

Adding multiple wireless network configurations

On recent versions of Raspbian, it is possible to set up multiple configurations for wireless networking. For example, you could set up one for home and one for school.

For example

network={
    ssid="SchoolNetworkSSID"
    psk="passwordSchool"
    id_str="school"
}

network={
    ssid="HomeNetworkSSID"
    psk="passwordHome"
    id_str="home"
}

If you have two networks in range, you can add the priority option to choose between them. The network in range, with the highest priority, will be the one that is connected.

network={
    ssid="HomeOneSSID"
    psk="passwordOne"
    priority=1
    id_str="homeOne"
}

network={
    ssid="HomeTwoSSID"
    psk="passwordTwo"
    priority=2
    id_str="homeTwo"
}