This guide will go over how to get a Raspberry Pi (or really any Linux system) on Google’s
Project Fi cellular service. If you already use Project Fi as your main cellphone service
provider then you can use their data only SIM cards to get your
Raspberry Pi online for relatively cheap depending on your use case.

I was able to power the 3G modem directly from the USB port on my Pi Zero. You’ll probably need a good USB power supply
to power everything.

I’ll be covering a couple of different ways to get all of this working. You will need:

The Jet 2.0 is basically a Huawei UMG366, similar to the Huawei E366 modem. I’m only able to get EDGE speeds
on it (both on Linux and on a Windows XP laptop with T-Mobile software) so I wouldn’t recommend getting it.

The first step is getting the OS to recognize the modem. There is a problem with some 3G USB modems in that they
simulate a virtual CD-ROM drive (ZeroCD mode). This drive has drivers and software needed by Windows and OS X to control
the modem, and once installed and running that software takes care of switching the device into modem mode. However this
trick doesn’t work well on Linux since we don’t (and can’t) use that software to do the switch. So we only see the
virtual CD-ROM drive (or SD card if it has one) and not the modem.

You can see this for yourself: plug in the modem into a USB port on the Raspberry Pi and run lsusb. You should see
something like this:

The above is NOT what we want. Even though it says “HSPA modem” it is in fact in ZeroCD mode. You won’t have wwan0
in ifconfig and you won’t see any /dev/ttyUSB* devices.

Tip

If you do see wwan0 in ifconfig or have /dev/ttyUSB* devices then you can probably skip following
sub-sections and head on over to the Dialing section below. On Raspbian Lite I had to use usb_modeswitch but on
Raspbian with PIXEL I didn’t need it.

There are two solutions to this: using USB Mode Switch software to switch to modem mode on Linux or the
“software-free” Permanent Modem Mode approach. I’ll explain both below:

A very common and safe solution is to use usb_modeswitch. Luckily it comes pre-installed on Raspbian. If for some
reason you don’t have it you can just run sudoapt-getinstallusb-modeswitch.

First cherry pick the correct file from configPack.tar.gz and put it in /etc/usb_modeswitch.d. Remember that if you had
something other than “12d1:1446” in your lsusb output you’ll want to use that device ID instead in the command
below.

This is a more risky yet robust solution. Unfortunately in my experience usb_modeswitch wasn’t very reliable between
reboots. I kept having to run the sudousb_modeswitch command to manually do the switch to modem mode. Since I plan
on keeping my Raspberry Pi unattended for weeks/months at a time I can’t be there to do the mode switch myself, nor do
I want to setup an ugly cronjob to do it (feels like a band-aid solution to me).

There is a way to disable this “switch” feature on my 3G modem using the SETPORT AT command (other Huawei modems
support the U2DIAG AT command but mine didn’t seem to have it). You can always reverse this change if you keep the
original values written down somewhere.

Warning

Be VERY careful with the SETPORT command. If you omit one of the modes you could accidentally lock yourself out
of the modem forever (e.g. excluding PCUI mode may cause /dev/ttyUSB0 to never come back).

We’ll need to issue AT commands to the modem. I’ll be using screen. You’ll need to have the /dev/ttyUSB0 file
present so if you don’t have it you’ll need to run through the USB Mode Switch section or run
sudosg_raw/dev/sr011062000000000000100 to temporarily switch to the modem.

Values before the colon are initial modes and values after the colon are post-switch modes. As you can see only the
CDROM and SD card modes are enabled by default until usb_modeswitch is run, which then includes the modem. We can use
the undocumented “FF” mode as a noop to just disable the special “initial” mode and always start off with the modem.

AT^SETPORT="FF;1,2,3,7"
OK
AT^SETPORT?
ff:1,2,3,7
OK

Exit screen, pull out the modem, and plug it back in. You should get wwan0 instantly.

You may currently have wwan0 present, but it doesn’t have a public IP address (you’ll have a
link-local address instead). We’ll need to issue “dial” commands
to the modem to get it connected (just like the old 56k days!). I’ve found a couple of different ways to do this: the
“easy” software-ppp approach WvDial and the Huawei-specific (but still safe) non-ppp approach NDISDUP.

wvdial should theoretically handle auto-redialing on disconnect and other edge-cases, though I haven’t tested it.
We’ll have it dial up with the Project Fi APN h2g2. Other cellular providers require a username and password to dial
but Project Fi doesn’t need that.

There is a way to skip needing wvdial altogether and let the modem handle it for us. Apparently though this only
works for Huawei modems (lucky for me). This isn’t a permanent solution so we’ll be automatically running this every
time the wwan0 interface is brought up.

If you read through the WvDial section, you’ll notice that network traffic goes through ppp0 instead of wwan0
and indeed wwan0 is never even used. It looks like wwan0 is a virtual NDIS ethernet adapter that the modem provides, yet
is usually unused. We’ll be using it here.

Before making changes lets try manually enabling it. Log into the serial console with a tty program (I’ll be using
screen):

You should have internet access now. To automate all of this we can create a pre-up rule for the network interface.
We’ll need the qmicli utility to check if we have cell service before trying to dial in with NDISDUP. It’ll also be
easier to use than issuing AT command with echo and not being able to find out if the command failed or succeeded.
Install it with sudoapt-getinstalllibqmi-utils. Edit /etc/network/interfaces.d/wwan0 with the following file
contents:

You should still have network access. Reboot to make sure it works. Unplug and plug back in while the system is running.
If it still re-connects just fine feel free to uninstall wvdial if you’ve previously installed it.

Tip

If the modem doesn’t auto-connect on boot but does after ifup try editing /etc/network/interfaces and
changing source-directory/etc/network/interfaces.d to source/etc/network/interfaces.d/*.

In my experience this setup seems pretty robust. I tried different reboot/power cycle/unplug/replug scenarios and I even
placed my Raspberry Pi in my microwave (poor-man’s grounded faraday cage) to block out cellular signals for a few
minutes. Every time the Raspberry Pi managed to re-connect automatically.