Send Mail from your Raspberry Pi

I have to go searching for how to do this every time. This time I thought I would memorialize the instructions. I found this in an article written by Stacy Prowell on

The first thing you need is some additional software. I am going to use Postfix, which is a mail transfer agent (MTA) — that is, something that knows how to talk to other MTAs to send and receive email. In particular, Postfix supports the simple mail transfer protocol (SMTP), so it can talk to nearly any other MTA out there, including Google’s Gmail. In case you don’t like Gmail, there are guides online like this one for getting Postfix to talk to other SMTP servers.

1. Install Postfix

Run the following command at the prompt to install Postfix along with simple authentication layer security (SASL), which Postfix will use to connect to Gmail.

sudo apt install postfix libsasl2-modules

During the installation, you will be asked about how the mail server should operate. You want an Internet Site, where email is sent and received directly using SMTP, so select that option.

Screenshot of package configuration screen
So many choices

Now you’ll be asked for the “system mail name.” You should use your hostname (raspberrypi, for instance) or, if you have a fully-qualified domain name for your network via your ISP or a service like DYN, then you can use that. Don’t stress over this; you can modify it later by editing the /etc/postfix/ file if you need to.

Screenshot of a package configuration dialog
Set the server name

2. Get an Application Password for Postfix from Google

have Google set up for two-factor authentication (2FA), so how will the Pi be able to send an email? Well, it turns out you can get Google to generate an application password, which is a password to allow a specific application to connect.

To get an application password head to: and log in.

Screenshot of Google account options
Account security settings

Select “Security” from the list on the left.

Screenshot of Google account security options
Manage your application passwords

Note that I have two-step verification turned on. You might or might not; either way, creating an application password for each application is a good idea. If you lose a device or it is stolen, you can revoke the application password and not have to change your existing password or passwords for other applications.

There should be a box for “Signing in to Google” that contains an option for “App passwords.” Click on that. You might have to sign in again at this point (I did). This should take you to the page to manage application passwords. The example account I am using doesn’t have any.

Screenshot of app password manager
Create a new application password

Now click on “Select app” and select Mail. Then click on “Select device” and select Other. You’ll need to enter the name of the device (for this example it is raspberrypi4). Click Generate to create the application password.

Screenshot of new application password
A new application password! Don’t get excited; I’ve already deleted it.

You should now be presented with a new application password. This is the text in the yellow block in the image above. Success! Do not click done! Copy the app password first, or write it down. You’ll need it and you can’t display it again.

3. Configure SASL

(A lot of the content of this section is taken from the Postfix SASL HowTo.)

We are almost done. The next thing to do is to add the app password you just generated to the SASL configuration. Run the following command.

sudo nano -B /etc/postfix/sasl/sasl_passwd

This command will open the file in an editor. It is likely the file does not exist, and you will see an empty file. Add the following line, replacing username and password with your Gmail username and the application password you just generated (don’t include the spaces).


This line tells SASL that when it connects to the host at port 587 to download mail, it should use the given username and password to connect. Exit and save with CTRL+x, y, and Enter.

This file contains a “clear text” password. Run the following command to protect that file.

sudo chmod u=rw,go= /etc/postfix/sasl/sasl_passwd

This command sets the user permissions (root) to read and write and removes any permissions for the group and others. (Fans of the numerical form of chmod will recognize this as 0600.)

Now turn this file into a hash file for Postfix. Run the following command.

sudo postmap /etc/postfix/sasl/sasl_passwd

This command will create a new file named sasl_passwd.db in the same directory. It should already have the permissions set correctly, but just in case, let’s also explicitly set the permissions.

sudo chmod u=rw,go= /etc/postfix/sasl/sasl_passwd.db

4. Configure Postfix

Now let’s finish up the configuration of Postfix. Run the following commands.

sudo cp /etc/postfix/ !#$.dist
sudo nano /etc/postfix/

Find the line (near the bottom) that starts with relayhost =. Here is where we specify that we want to use Google’s SMTP server as our relay host, and this must match what we put in /etc/postfix/sasl/sasl_passwd. Change the line so it looks as follows.

relayhost = []:587

Next, add the following to the end of the file. (Documentation for these options and others can be found here.)

# Enable authentication using SASL.
smtp_sasl_auth_enable = yes
# Use transport layer security (TLS) encryption.
smtp_tls_security_level = encrypt
# Do not allow anonymous authentication.
smtp_sasl_security_options = noanonymous
# Specify where to find the login information.
smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd
# Where to find the certificate authority (CA) certificates.
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

Save and exit with CTRL+x, y, and Enter, and then restart Postfix with the following command.

sudo systemctl restart postfix

5. Testing Email

Next, let’s verify that we can send an email via Google’s SMTP server. Type the following at the command line, replacing username with your Gmail user name (so the email goes to you).

Subject: It works!
Hey, it works!

The first line uses the sendmail command to send an email to the specified recipients (you can list more than one). The subsequent lines optionally specify mail headers like the subject, and then the body of the email. The entire thing is terminated by a period. Note that this is just one way to send email using the sendmail command. Later we will use sendmail to send the output of commands.

Check your email. If you got an email from yourself (remember: Postfix is using your credentials) then everything is working. If you didn’t, then you should check a few places on the system.

Checking for Problems

The most obvious problems are an inability to reach the Gmail server and a failure to authenticate with the Gmail server.

Inability to reach the Gmail SMTP servers

Make sure the network is connected and see if you can reach the Gmail SMTP server. The easiest way to do this is to “ping” If you see a failure message like “ping: Name or service not known,” then you should check your network connectivity. (It is possible that your ISP or the Google service itself is down… but this is less likely.)

Failure to authenticate with the Gmail SMTP servers

To see this, check the file /var/log/syslog for messages from postfix. If you see a message like the one below, your credentials were not accepted.

Dec 10 08:04:01 raspberrypi postfix/smtp[18329]: 331F960582: SASL authentication failed; server[] said: 535-5.7.8 Username and Password not accepted. Learn more at?535 5.7.8 c188sm1372198ywb.56 - gsmtp

Check that the content of /etc/postfix/sasl/sasl_passwd is exactly what it should be, and make sure you ran the postmap command to create the hash file. If everything looks correct, or if you don’t have your application password written down, go back to Google account management and delete the old application password, create a new one, and carefully add it to /etc/postfix/sasl/sasl_passwd and then run the postmap command given earlier.

Adding Email Aliases

You can add email aliases by editing the file /etc/aliases and then running the newaliases command. This can be used to tell Postfix how to handle local email addresses.

For example, perhaps you want email to the pi user to go to your Gmail account. You would run the following command to edit the aliases file.

sudo nano -R /etc/aliases

Next, you would add the following line, where username is your Gmail username.


Finally, tell the system about the new mail aliases by running the following command.

sudo newaliases

Now mail sent to pi will be forwarded along by Postfix to your Gmail account.

Depending on what you are using the Pi for, you might forward postmaster, webmaster, or other names. Note that these don’t have to correspond to any local account.

Sending Text Messages

A computer in our server room sends me a text message each morning using a dedicated cellular long term evolution (LTE) modem. The Pi doesn’t have one (though you can buy them; for instance, here’s one), but if you’ve successfully followed the above instructions, your Pi can send email, and it turns out you can send a text message by first sending an email.

First, a word of warning. Sending an email over a connection to Gmail isn’t likely to cost you any more than you are already paying for internet connectivity. But receiving a text message on your phone just might. Check your plans, and be courteous of other people who might not want unsolicited text messages from you.

Email to Text

Cellular providers will convert emails sent to a special address into text messages, and forward them along. Text replies may be converted back to a return email, but this is less certain. The two articles below cover this in some detail and provide information for both short message service (SMS) and multimedia message service (MMS), where supported.

Here are the top four North American providers and the information for each. (Apologies to non-North American readers; there are far too many wireless services around the world for me to try to include them all.)

Service Name SMS Email Suffix MMS Email Suffix
AT&T Mobility
Verizon Wireless
T-Mobile (same)
Sprint Corporation

You use these by finding the provider for the recipient of the message, and then sending an email to the ten-digit (North American) phone number followed by the appropriate email suffix.

For instance, suppose your cell phone number is (724) 555–1212, and your provider is Verizon. Then you can send yourself a text by sending an email message to the address These SMS messages are typically limited to 140 characters.

You can also send MMS messages, but this is a bit more complex.

Email to Text from the Raspberry Pi

My carrier is Sprint, and my number is (not really) 724–555–1212. So to send a text to my phone I can send a short text email to Let’s try a test.

At the prompt of the Raspberry Pi, try the following (replacing the address with whatever is correct for your cell phone).

echo "Test" | sendmail

You should receive a text on your phone.

Screenshot of a text message

Great! If you don’t, check your Gmail for a delivery failure notice, and make sure you are using the correct address for the recipient (you, in this case).

Reply to Text

What happens if you reply to a text? Well, that depends on your service provider. For my provider (Sprint) an email is created and sent.

Reply email
Talking back to the text

You can reply to this email, and the result will be a (possibly very ugly) text message. Communication achieved!

Note that if you are getting your hopes up on automatically processing the replies, you should be careful. The reply above was sent as a base 64 encoded rich text file. That is, you may have to do some work if you want true two-way communication.

Things to Say

Now that you can send email and text messages from the Pi, what should the Pi say? Well, as mentioned at the start, I set my Pi up to be a file server, and so one thing I would like is a report on the file system usage each morning when I get up. I’m also mildly paranoid, so I’d like to know when someone logs into the Pi. One is almost trivial. The other requires a bit more work.

This would be a good time to add an alias for text messages. For example, you might add the following line to your /etc/aliases and then run sudo newaliases as described previously.


From now on you can just send email to alert, and Postfix will turn it into a text message to your phone.

Reporting File System Usage

I am using two drives to store information: /data/a and /data/b (I’m not that creative). I can check on the file system used with the following command.

df --output=target,pcent /data/a /data/b

(I only want to know about those two file systems; if I did not include them, the df command would list all the mounted file systems… which might be what you want in some cases.)

This tells me exactly what I want to know: how much space is used in each file system. If this space gets too high, I know I need to add more storage. This is the output from the above command as I write this.

Mounted on Use%
/data/a 3%
/data/b 2%

It’s short and simple, under 140 characters, and a perfect thing to text to me in the morning to let me know the status of my file server. I can drop the header line and send the output with the following command, using the alert alias we created at the start of this section.

df --output=target,pcent /data/a /data/b | \
tail +2 | /usr/sbin/sendmail alert
A screenshot of text messages
Success! Information you can ignore until it gets out of hand.

(The tail +2 tells the system to copy all output from the prior command, starting at the second line… so this skips the header line.)

Great! Now I want this to run as a command every morning at 6:00 am. For that, I will use the Linux cron utility.

Every user has a special file called the crontab that contains information on commands to execute, when, how often, etc. Do not edit this file directly! There is a special command, crontab, for examining and editing this file.

The following command will list the content of the user’s crontab file.

crontab -l

By default, each user gets a crontab file with a helpful usage message as a series of comments. You should leave these comments in for reference!

# Edit this file to introduce tasks to be run by cron.               
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# For more information see the manual pages of crontab(5) and cron(8)
# m h dom mon dow command

Now let’s add a line to generate the file system usage message every morning at 6:00 am. Note that we want to run more than one command, so we need to enclose the whole thing in parentheses. If we were running a single command we would not need the parentheses.

To edit the crontab, run crontab -e. This will open your crontab in an editor. Add the following line, below the format comment, save, and exit.

# m h  dom mon dow   command
0 6 * * * ( df --output=target,pcent /data/a /data/b | tail +2 | /usr/sbin/sendmail alert )

The minutes (m) is zero, the hour (h) is 6 (using 24 hour time), we want every day of the month (dom), every month (mon), and every day of the week (dow), so we set those three to asterisks (*). Alternately, if I just wanted a report every Friday afternoon at 5:30 pm, I would write the following.

# m h  dom mon dow   command
30 17 * * FRI ( df --output=target,pcent /data/a /data/b | tail +2 | /usr/sbin/sendmail alert )

If this seems much too tricky, don’t lose hope. Head over to the Crontab Guru site for help. You can (and I do) have multiple lines in your crontab to do a variety of things. If you want to know more about how crontab works, the file format, etc., see Ranjan Bajracharya’s article on cron jobs.

Reporting SSH Logins

I have the Pi set up to allow remote logins using two-factor authentication. I wrote a short article on how to do that, too.

Setting Up SSH and 2FA on a Raspberry PiLog in from anywhere using SSH and Google

Because the Pi is accessible remotely, I’d like to be alerted when someone logs in via SSH. Doing that is pretty easy, it turns out. (Of course, this is only going to work is you have enabled SSH.)

First, create a new script. We’ll put this in the /etc folder.

sudo nano /etc/

The content of the file should be as follows. (Note that this script depends on the alert alias created at the start of this section. It is a Really Good Idea to try to capture this sort of information in a single place and not scatter it around the system!)

SUBJ="Alert - Remote SSH access from ${PAM_USER}"if [ -z "$PAM_TYPE" -o "$PAM_TYPE" == "open_session" ]
thensendmail alert <<END
$(hostname) $(date): LOGIN by ${PAM_USER} from ${PAM_RHOST}
ENDelsesendmail alert <<END
$(hostname) $(date): LOG OUT by ${PAM_USER} from ${PAM_RHOST}

Next, we need to arrange for the Linux pluggable authentication module (PAM) system to invoke this script whenever someone logs in or logs out via an SSH session. Run the following command.

sudo nano -R /etc/pam.d/sshd

Let’s protect the file against changes.

sudo chmod go-w /etc/

Add the following lines at the end of the file.

# Notify on successful login / log out.
session optional /etc/

Now log into the Pi via SSH and make sure you get a text message. You should get a shorter message when you log out.

Screenshot of text messages reporting login and log out
Watching log in and log out. The list of users in the first message includes the console user (tty1)

You can do a lot of other things with PAM; details are beyond this short document, but there are many excellent articles that cover this important system.

BrewPi on Bluetooth

Over on Homebrew Talk, @day_trippr shared a way to connect the Arduino to your Raspberry Pi over Bluetooth. That was December 14, 2014 and a lot pf people have been successful with that. I personally found a couple of the steps a little challenging. To be fair, that’s a personal shortcoming and not one of the original article. Still I searched for a way to make it a little easier and I think I’ve found it. I’ll share here what I’ve come up with in the hopes that someone else will find it useful.

This tutorial is for Windows users. I expect Mac and Linux users will have to use the “old fashioned” way.

On Amazon I found a package with an HC-05 Bluetooth Module, a case for that module, Dupont jumpers, and a CP2102 USB to TTL Converter for $12.99 on Prime. That seems like a pretty good deal and provides some pretty good value for a person new to it. When you get a drawer full of “crap”, the Dupont wires certainly have less value, but I kinda like the case. So, I’m writing this with that USB to TTL Converter being used:

You can find it on Amazon here. Buy that and come back.

Hardware Setup

Without further adieu, let’s get started. Don’t plug the adapter in your computer yet. You’ll need to download some software to get going. You’ll probably need the CP2102 drivers, and to follow this you will definitely need the DSD TECH Bluetooth Tools Software. Download and install both of these (actually the “Bluetooth Tools” doesn’t install, just unzip to a handy directory):

Don’t plug the converter into the USB on your computer yet. Connect the TTL converter and the BT module like so:

I actually used the 3.3v the first time, the module will run on 3.3-6v for VIN I believe, but the data channel needs to be 3.3 volts. No worries, the USB to TTL converter handles that for you. Here’s the connections in text form:

Converter PinHC-05 Pin

Basically, remember to connect transmit to receive and vice versa. When you are ready and the jumpers are connected properly, connect the device and set programming mode (called “AT mode”) by doing the following:

Input low level to PIN34, supply power to the module, input high level to PIN34, then the module will enter to AT mode.

Just kidding, I have no idea what that means either. I promised this would be for mortals. 🙂

  1. Hold the button down on the Bluetooth Module (note about some of the modules sold elsewhere which are insulated with shrink-tube: You may have to cut the tube away from the button in order for it to function correctly)
  2. Plug in the USB to TTL Converter
  3. The light will come on for about a second, and then shut off
  4. Let go of the button on the Bluetooth Module

If you have done this correctly, the module should be flashing on and off slowly. Done incorrectly, the device will be flashing rapidly. If you don’t get it the first time, unplug the converter and try again.

Now run the “DSD TECH Bluetooth Tools Software” you unzipped. You will be executing “SHTester.exe”.

  1. Select the last tab which is “HC-05”.
  2. Drop down the UART box and select the port. On most systems there will be only one. If you have some other COM port device installed there may be more than one listed. If this is the case you will need to open Windows’ “Device Manager”, look under “Ports (COM & LPT)”, and see what COM port is associated with the “Silicon Labs CP210x” device.
  3. Set Baud Rate to 38400, then click “Open”.
  4. Click the “Test” button, and in the status windows you will see the “AT” command being sent and “OK” received. This will not work unless you are in AT mode (slow flashing). If you don’t get anything back it’s likely a Baud Rate mismatch. Click on “Close”, select a different Baud Rate, “Open” and try testing again till you get an “OK” back.
  5. Now set “Bluetooth Name” to whatever you’d like it to be, Baud Rate to 57600, PIN (really no reason to change the PIN but if you do, remember it), and set Role to “Slave”. Click “Set” after each change.
  6. Now “Close” the UART up top again with the red “X” and you can close the app.

If you’d like, you can test the device over Bluetooth from your computer:

  • Unplug the USB dongle and unplug the two TX and RX wires.
  • Plug it back in and now the Bluetooth Module will be flashing rapidly indicating it’s ready to be paired.
  • Open the Windows Bluetooth settings and click “Add a device.”
  • Select the name you gave the module above and enter the PIN you used.
  • Click “Connect” and if successful, the device will flash briefly every two seconds or so.

Congratulations! You can unplug the device now, it’s ready to be connected to your Arduino.

This is where you can go a couple different ways. In order to connect to your Arduino you do need to either use a voltage splitter to step the voltage down to 3.3v, or if you are using @CadiBrewer’s shield, this is done for you. This has to be done because the logic on the HC-05 module can only handle 3.3 volts, and the TX channel on your Arduino is at 5 volts.

If you are using the shield version 1.1, connect as follows:

Shield PinHC-05 Pin

If you are using the shield version 1.2, reportedly the RX/TX line up directly so connect as follows:

Shield PinHC-05 Pin

If you are going all rogue and want to do it without a shield, at least you were able to skip the whole Arduino sketch setup thing initially. You will need the following:

  • 1 x 1K ohm resistor (1/8W axial)
  • 1 x 2K ohm resistor (1/8W axial)
  • Assorted Dupont jumpers

Wire them according to this diagram so that the voltage into the RXD pin on the module is cut to 3.3v:

Software Setup

Setting this all up changed since the article @day_trippr posted. I am NOT sure when this changed. @day_trippr is running Wheezy and Jessie and his original article uses the “old” way of setting up a Bluetooth device. I’m using Stretch with bluetoothd 5.43 and the method by which you set up /dev/rfcomm* devices with the rfcomm.conf file in /etc/bluetooth in Wheezy and Jessie is no longer supported. I’m sure someone somewhere could tell me WHY this is better. I’m sure we’d hear some crap about “cloud-enabled” like they tell me with all my favorite Ubuntu items that no longer work.

Anyway, here’s how you can get the devices enabled with Stretch. To start with, make sure your HC-05/6 is powered up in its production configuration (i.e. baud rate and slave mode as detailed above). At this point it’s probably flashing 2-3 times per second. Then, prove to yourself that there’s no rfcomm* devices:

pi@brewpi:~ $ ls -al /dev/rfc*
ls: cannot access '/dev/rfc*': No such file or directory

Next, execute the new CLI for bluez, “bluetoothctl”:

pi@brewpi:~ $ sudo bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX brewpi [default]

The controller listed is your local Raspberry Pi’s controller. We need to turn on and configure the “agent” which is the process that allows you to enter the pairing codes with Bluetooth devices when required:

[bluetooth] # agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful

The next thing to do is allow the system to scan for local devices. If you have a “busy” area bluetooth-wise, you may get a lot of spam. Just let it run about 10 seconds and if you are living a clean life you will see your target Bluetooth device and it’s MAC address. After that you can turn off the scan.

[bluetooth]# scan on
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[NEW] Device XX:XX:XX:XX:XX:XX [TV] Living room
[NEW] Device XX:XX:XX:XX:XX:XX Chamber 1
[bluetooth]# scan off
Discovery stopped
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: no

You may have to scroll up to find it, but if you gave your HC-05 a friendly name when you set it up (“Chamber 1” in my case), you should see the MAC followed by that name. Next, you will pair with your device with the pair command followed by the MAC address. It will prompt you to enter the code which is generally 1234 or 0000 unless you changed it:

[bluetooth]# pair XX:XX:XX:XX:XX:XX
Attempting to pair with XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device XX:XX:XX:XX:XX:XX UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device XX:XX:XX:XX:XX:XX ServicesResolved: yes
[CHG] Device XX:XX:XX:XX:XX:XX Paired: yes
Pairing successful
[CHG] Device XX:XX:XX:XX:XX:XX ServicesResolved: no
[CHG] Device XX:XX:XX:XX:XX:XX Connected: no

Next you will “trust” the HC-05:

[bluetooth]# trust XX:XX:XX:XX:XX:XX
[CHG] Device XX:XX:XX:XX:XX:XX Trusted: yes
Changing XX:XX:XX:XX:XX:XX trust succeeded

At this point your BT dongle is probably flashing once every two seconds. It’s paired and trusted as you can see by issuing the ‘info’ command:

[bluetooth]# info XX:XX:XX:XX:XX:XX
Name: Chamber 1
Alias: Chamber 1
Class: 0x001f00
Paired: yes
Trusted: yes
Blocked: no
Connected: no
LegacyPairing: yes
UUID: Serial Port (00001101-0000-1000-8000-00805f9b34fb)

I noticed that if you power-cycle the Bluetooth device at this point, it will go back to flashing 2-3 times/second but that doesn’t seem to affect things. You can exit or quit back to the shell prompt:

[bluetooth]# exit
Agent unregistered
[DEL] Controller XX:XX:XX:XX:XX:XX brewpi [default]
pi@brewpi:~ $

So, it’s paired and trusted but still not visible in the device list as you can see if you list it out:

pi@brewpi:~ $ ls -al /dev/rfc*
ls: cannot access '/dev/rfc*': No such file or directory

To add it to the device list, we need to bind it to a device with the following command:

pi@brewpi:~ $ sudo rfcomm bind 0 XX:XX:XX:XX:XX:XX 1 > /dev/null 2>&1 &
[1] 3345

It seems like the command runs till something touches the device (which is why we background it with the trailing ‘&’.) In that command the ‘0’ is the rfcomm device we want to assign (i.e. /dev/rfcomm0), the MAC address should be obvious, and the 1 is the channel. Unless you know why you want to change the channel, use ‘1’. Now prove there is a device in the list (and see the background process exit):

pi@brewpi:~ $ ls -al /dev/rfc*
crw-rw---- 1 root dialout 216, 0 Mar 16 13:31 /dev/rfcomm0
[1]+ Done sudo rfcomm bind 0 XX:XX:XX:XX:XX:XX 1 > /dev/null 2>&1
pi@brewpi:~ $

Power-cycling the BT device at this point proves the device will reconnect after a power failure after about 10 seconds. What does not happen however is the connection will not re-establish to the device after a Raspberry Pi reboot or power failure. We need a way to issue the rfcomm command after every reboot (and after the bluetoothd starts.) Create a file named ‘rfcomm0.service’ in the ‘/etc/systemd/system/’ directory:

sudo nano /etc/systemd/system/rfcomm0.service

Add the following information:


ExecStart=/usr/bin/rfcomm bind 0 XX:XX:XX:XX:XX:XX 1 > /dev/null 2>&1 &


This will allow systemd to execute the rfcomm command binding that MAC to rfcomm0 after the bluetooth.service starts. To enable this unit file, issue the commands:

pi@brewpi:~ $ sudo chown root:root /etc/systemd/system/rfcomm0.service
pi@brewpi:~ $ sudo chmod 664 /etc/systemd/system/rfcomm0.service
pi@brewpi:~ $ sudo systemctl daemon-reload
pi@brewpi:~ $ sudo systemctl enable rfcomm0
Created symlink /etc/systemd/system/ → /etc/systemd/system/rfcomm0.service.
pi@brewpi:~ $

You can start it with the ‘sudo systemctl start rfcomm0’ command, but there’s no reason to since it’s already bound (assuming you ran the bind command above and have not rebooted – it will not hurt if you run it again). If you check the status of this daemon after system reboot it will not be running, because it ran once and exited – which is all we needed it to do:

pi@brewpi:~ $ sudo systemctl status rfcomm0
● rfcomm0.service
Loaded: loaded (/etc/systemd/system/rfcomm0.service; enabled; vendor preset:
Active: inactive (dead) since Sat 2019-03-16 13:43:59 CDT; 40s ago
Process: 290 ExecStart=/usr/bin/rfcomm bind 0 XX:XX:XX:XX:XX:XX 1 > /dev/null 2>&1 & (code=exited, status=0/SUCCESS)
Main PID: 290 (code=exited, status=0/SUCCESS)
Mar 16 13:43:59 brewpi systemd[1]: Started rfcomm0.service.

That’s how you set up your BT devices now in Stretch! You’ll notice that using the graphical interface is also not needed. Using this method, no additional packages are required as a matter of fact, all the packages are part of the stock Raspbian Stretch distribution.

If you have multiple Bluetooth devices, you’d change the above steps using 1, 2, 3, etc., instead of 0. You would also need a systemd unit file for each device named appropriately.


If you want to give it a test outside of BrewPi, you will need to install a program called “screens”:

sudo apt install screen

Next, run ‘screen’ and connect to that device with the proper baud rate:

sudo screen /dev/rfcomm0 57600 

If you are living a clean life, you are now connected to your Arduino. Issue the command ‘l’ (lower-case L) and the controller should print the LCD screen information; something like this:

L:["Mode   Off          ","Beer   60.7  --.- �F","Fridge 61.2  --.- �F","Idling for     03m08"

You need to type “ctrl-a” and then “k” to kill the screen session.

Configure BrewPi

In order to connect this to BrewPi, you will edit (or create) your config.cnf file to look something like the following:

scriptPath = /home/brewpi
wwwPath = /var/www/html
port = /dev/rfcomm0

This works in Legacy BrewPi as well as all versions of BrewPi Remix.

BrewPi on WiFi

One of the most common “wishes” for BrewPi users is to be able to connect the Raspberry Pi to the Arduino wirelessly. This makes even more sense and is more desirable when you leverage a multi-chamber setup. The Arduino Uno did not have WiFi originally, although the nice folks over there in Italy have a Rev 2 of a WiFi enabled Uno for the low low price of $44.90. I don’t know for sure, but since (I believe) this is a native implementation, I suspect any Uno sketches would need to be re-written for WiFi.

That’s a problem for BrewPi where we are getting close on storage space anyway.

Not to fear though! Back in 2015, @thekraken on HomebrewTalk started talking about how to make an ESP8266 work as a serial bridge. That was really just sort of a technical discussion, and it never quite rose to the level of something that seemed practical for most end users. About four months after that, @day_trippr took a swing at it and came up with a start to finish method of doing it for the courageous, but let me just tell you that dude is “wicked smaht” and what’s easy for him is not generally easy for a guy like me.

People kept pecking at it but rather than me give you the blow by blow, you can read it yourself on HomebrewTalk. BUT, I figure you want to know how to do it, or else, why are you here. Amirite?

So, here’s what you need:

  • A Raspberry Pi (duh!)
  • A combo ATmega328P+ESP8266 card direct from China. The ATmega328 is the guts of an Uno. The ESP8266 is a controller in its own right, but we are using it as a WiFi/Serial bridge. I used this one from Banggood in my project. I don’t have any reason to believe that there are not many others that would work. I paid $6.49 + shipping so I bought a couple just in case one arrived DOA.

To start with, go ahead and install BrewPi Remix if you don’t have it installed already. No need to connect the Arduino just yet. Take the defaults, smile and nod your head if the script tells you there’s no Arduino, and don’t worry about flashing the controller (yet.)

You might need to Google up some drivers for the CH340 chip if you will be using your PC for this (and expect my instructions to work), unless you’ve messed with one of the Uno clones before. The “official” drivers appear to be on this page in Chinese. You can either translate or click on the very obvious download button and throw caution to the wind.

Install those drivers, and find yourself a USB micro cable because this board ditched the HUGE type “B” plug. Before you plug it in, you need to set the DIP switches as follows to let the CH340 talk to the ESP8266:

Switch NumberPosition
8 (Do Not Use)Off

Go ahead and plug the board in to your PC to hear the pleasing “boing” letting you know that it connected. You’ll need the NodeMCU Firmware Programmer if you have not already downloaded it before. You can get it here. If you don’t know whether you are on a 32 or 64-bit system, just grab the ESP8266Flasher.exe file from the Win32/Release directory.

You will also need some firmware for the ESP8266 side. First, download “ESP-Link” version 3.0.14 from the releases page (read the notes and get the latest stable version.) Previous versions of this article had instructions to use 2.2.3 versions, but the 3.0.14 firmware seems quite stable. Unzip those files somewhere handy and continue.

Go ahead and execute the NodeMCU Firmware Programmer (“ESP8266Flasher.exe”) and set up the following firmware files at the addresses indicated on the “Config” tab:

File NameMemory AddressDescription
user1.bin0x01000ESP-Link Firmware v3.0.14
esp_init_data_default.bin0x3FC000Expressif Default BIN
blank.bin0x3FE000Blank WiFi Settings

The numbers are memory addresses so do be careful and don’t select the wrong one. At best things will not work. At worst you will brick your card.

If you are curious about the “Advanced” tab, I did not make any changes. The settings were:

Setting NameSetting
Baud Rate230400
Flash Size4MByte
Flash Speed40MHz

On the “Operation” tab, select the proper COM port, then click “Flash”.

When complete, go ahead and close the programmer, unplug the card, and set the switches to connect the CH340 to the ATmega328 (upload sketch to the ATmega328):

Switch NumberPosition
8 (Do Not Use)Off

Now flash the BrewPi Remix firmware with whatever tool you like. I just plugged it into my Pi and used “sudo /home/brewpi/tools/” since that script downloads the latest firmware automatically. In theory this board will allow flashing the ATmega328 over the air, I’ve just not tried that yet. Once you have the BrewPi firmware loaded, unplug and set the switches to connect the ESP8266 to the ATmega328 (serial bridge mode):

Switch NumberPosition
8 (Do Not Use)Off

Power the board up separate from your PC or Pi. Now from your computer, phone, or whatever; search for the access point created by the board. It will be something like ESP_XXXXXX. Connect to it, no password needed. Open your web browser and navigate to After a moment the esp-link page will show up. Go to the “WiFi Station” tab, and follow along. Click the link under “WiFi State” to switch to STA+AP Mode:

Select your desired wireless network (if they do not show up, refresh the page) and provide the proper password. When done click the Connect! button:

After it connects successfully, record the WiFi IP Address under “WiFi State.” For the purposes of demonstration, we’ll assume it’s

Now connect your PC to your normal network and connect to the board again via it’s new address ( Go to the µC Console tab and set the following:

  • Switch Baud Rate to 57600
  • Click the Reset µC button to commit the change.

Now press the MCU RESET button on the controller (or simply power-cycle by pulling the plug.) If you left it on the µC Console tab, you should see json from the controller in the console window after reset is complete. Success!

The last step is to configure your BrewPi instance for the controller. Assuming you are using a custom config (config.cfg), change the port to point to your board’s IP address and port 23 like this:

scriptPath = /home/brewpi
wwwPath = /var/www/html
port = socket://

This will work on all versions of BrewPi Remix starting with Changes to the python scripts would be necessary to use this with Legacy BrewPi. Re-start your script and you should be connected via WiFi!

One thing I came across which requires a small hardware change: If you are using one of @CadiBrewer’s shields with the LCD you will notice that the LCD does not work. This is because the shield attempts to separate the power for the shift register and LCD from the rest of the board by taking power off the ICSP header. This header does not line up with the ICSP header on the combo board. So, you must jumper 5 volts and a ground (+5V and GND) off the header on the shield to the ICSP header on the shield and all will be well.

Obviously this shows the Arduino and not the shield, but the headers are all in the same place.

BrewPi Hardware

There’s two very important points I need to share about this:

  • Without the start FuzzeWuzze gave us on the “Mega Thread” on, a lot of us would never have successfully made our first rig. The first post is dated, the thread incredibly long (but still full of AWESOME info), the various fan Wiki’s also dated, so I wanted to persist for as long as I could how a person can put together the hardware
  • There are as many ways to do this as there are people doing it. This is ONE WAY it can be done. If you are smart enough to deviate from this, you should be smart enough to figure it out yourself. Please don’t ask me why your new idea doesn’t work

This post will share how to put the hardware supporting BrewPi together in the most basic way with which I believe a person can be successful. It is not meant to be “production ready”, it’s meant to show how it works on the bench so that the DIYer can add a case, etc., and use it on their fermentation chamber.

What you need

I’m not going to suggest which ones of these to buy, but I will give you some pictures that, along with the name/description, should be about all you need to find them on the Internet. I’ll give you a hint: I got all of these pictures except for the thermowell off Amazon. For the thermowell, seek out Brewers Hardware:

A fridge that you can “hack”. This can be as simple as keeping a fridge’s thermostat all the way on cold and plugging it into the system so that it only turns on by the BrewPi system. Most modern refrigerators use timers and such which make using them a little less straightforward. If you have what is commonly sold as a “kegerator”, it will work pretty well as it lacks auto-defrost, etc. This article will not detail how to hack a fridge (maybe some future article will), it will assume you are using one of those “kegerator” style boxes.

A working Raspberry Pi. This article will not detail how to setup the Raspberry Pi, nor address the software part of the build – that’s done elsewhere.

An Arduino Uno. I recommend not trying to get the cheapest one possible straight from China, and until you know why; avoid the ones that state they have a “CH340”. You can get a genuine Arduino Uno R3 on Amazon for $20, and decent clones for about $11. Get a USB A to B cable while you are at it if it does not come with one.

A 2-channel 5-volt relay, commonly the “SainSmart 2-Channel Relay Module” or a similar model.

A 15A 115v electrical outlet (if you are not in North America, modify this accordingly).

A “euro-style” wire connector strip, three stations will be needed. You can do this with anything, a breadboard, wire nuts, go wild. The first time I made this, this is what I used and it worked well.

One 4.7k Ω 1/4 watt axial resistor (sometimres you see this called a 4k7 Ω ). You are unlikely to find a single of these for purchase, they are pennies a piece. Pretty much anything you find that says 4.7k Ω 1/4 watt that looks remotely like the ones on the left will be fine.

Some 22 gauge Dupont jumper wires in male to female and male to male. You can generally get an assortment of gender combinations in various colors for a few bucks.

Some 16 or 18 gauge stranded wire, in black and red. You won’t need much of this, maybe a foot each. You can even cannibalize some from the next item.

A 16 or 18 gauge (16/3 or 18/3) grounded power cord. An old computer cord is a pretty good item for this if you have one.

(Optional) a “Ceramic Heat Emitter” in 60 or 75 Watts, commonly sold as a reptile heater bulb. Many indoor implementations will never need a heater, but if you have this in an unheated garage or shed in a cold climate, some form of heating will be required. Some folks have used a “personal heater” but even 100w is pretty hefty for this application – a light bulb is enough heat but you don’t want light in the chamber to prevent skunking your beer.

You’ll also need a lamp/cord/receptacle to support a lamp inside the fridge (if you decide to use one.)

(Optional) a small “personal sized” fan for inside the fridge to eliminate dead spots. Nothing large, whatever you have and will fit will work.

At least two DS18B20 sensors (called “one-wire”). Getting “waterproof” sensors with leads is important. Make sure they are directly powered and not parasitic. Searching the reviews and/or BrewPi threads will help you get known good items. Also make note of the wiring/color scheme from the manufacturer. You will need this. It’s nearly always listed with the item’s description.

(Optional but HIGHLY recommended) a stainless-steel thermowell. You won’t need this for bench-testing this of course, but using a thermowell for the “beer” sensor is much better than any of the other methods for getting a good beer temp. Make sure the sensors fit in the well.

Putting it Together

I could blather on about how to put this together, but I think a picture is worth a thousand words. This is a diagram done by 100Amps on Homebrewtalk that suffices for those 1000 words:

Arduino Electrical Connections

There are few things that while clear on this diagram I have managed to screw them up or allowed them to confuse me (or allowed me to confuse myself):

  • You can tie all of the One-Wire sensors together as shown since they are digital and have their own internal addresses
  • The “data” leg of the one-wire sensors go to the A4 terminal on the Arduino, power the terminal marked “5v” and the ground to “GND”. Each manufacturer of the sensors seems to change the colors around, so you will have to refer to the manufacturer for which color is which
  • A one-wire sensor (or many of them tied together) requires a single 4.7k Ω resistor between power and data in order to function correctly. This is called a “pull-up resistor” if you want to Google it. It looks strange but it’s necessary
  • There is a jumper on the hot side of the outlet that can be broken off with a pair of pliers which allows them to be powered separately – we use this to independently turn on and off the heat and cool

Step by Step Wiring

Refer to the wiring image above as you go through these instructions. The colors need not be the same, but if you keep them consistent you will thank yourself for it later. Print the pic (in color) to make it even easier to reference as you follow along.

Low Voltage Wiring

  1. Get your Raspberry Pi running, get logged in, play with it if you want. You can follow these instructions in the Raspberry Pi pages. You need not make it headless, do it however you want. The videos on the Raspberry Pi website are really good as well. All you need is the Raspberry Pi running, and able to connect to the Internet.
  2. Connect your Arduino to your Raspberry Pi with a USB A to B cable. This serves for both communications and power. Nothing will really happen yet other than an LED lighting up on the Arduino.
  3. Install BrewPi Remix just to make sure your primary pieces are working correctly. Doing it now avoids any confusion later on when you add the rest of the wiring. You’ll know it works before you end up adding more “stuff.” When you are done, the screen will tell you the URL you may use to access your new BrewPi installation. Open it up in a web browser and enjoy it for a moment! When you are satisfied it works enough to open up the page, you can come back here and worry about the rest of the hardware.
  4. Unplug your Arduino from your Raspberry Pi (you do not need to power down the Raspberry Pi first) before you proceed.
  5. You are now going to use your Dupont wires. Grab three different colors of your male to male wires and plug one each in the Arduino’s 5V, GND and A4 (this is your “data” port). These are all on the same side of the Arduino, on the same side as the black power inlet. Pick separate terminals on your Euro-connector, whichever ones you like, and run them there. No need to tighten things up right now.
  6. Take a couple of Dupont wires, male to female, which match your 5v and GND wires. Put the male ends into the corresponding Euro-connector terminals (obviously easier here if you use the same colors as your first two wires.) Again, just snug, no need to tighten.
  7. Take your 4.7k Ω 1/4 watt resistor and connect it between your A4 (data) connector and your power (5V) connector.
  8. You should now have two wires coming into the ground (GND) terminal, two wires plus one side of the resistor into your power (5V) terminal, and one wire plus the other end of the resistor into your data terminal (A4). You can snug them down now if you wish.
  9. Now take at least one (I recommend two) of your temp sensors and referencing the manufacturer’s layout, connect all of the ground leads into the other side of the GND terminal. Connect all of the power leads (may be referenced as VCC) to the other side of the power (5V) terminal. Connect all of the data leads to the other side of the data (A4) terminal. One sensor will be your “beer” sensor and the other the “chamber” sensor.
  10. Now you will connect your 2-channel relay. Take a look at the low-voltage side first. It will have two small male pin strips; one three pins and one four. The three pin strip should have a jumper (probably a small blue or black cap) between JD-VCC and VCC on the strip of three pins. This allows the relay to be powered by the Arduino.
  11. Now you will connect your leads from power (5V) and ground (GND) out of the terminal block to the relay. 5V goes to VCC, GND goes to GND.
  12. Take two more Dupont jumpers, male to female, of differing colors. These will represent heat and cool so maybe blue and orange would be good. Connect one to digital pin 5 and one to digital pin 6 (likely marked ~5 and ~6) on the opposite side of the other connections (USB connector side). At this point it doesn’t matter which is which, you will be able to set the pins later.
  13. The other ends of these jumpers will go to the IN1 and IN2 terminals on the 4-pin strip on the relay.

Your low-voltage wiring is now complete. You can go ahead and plug your Arduino back into your Pi. Refer to the instructions to set up your probes and relay pins and get to know your system. Experiment and test now before proceeding. I recommend a digital multi-meter to test the continuity at the high-voltage side of the relays so you can get the hang of how things work before actually applying high voltage. You can also view the LEDs on the relay card.

There’s nothing about any of the low voltage we’ve done so far which will be harmful to you. You might short some of the circuit logic if you are careless and allow things to touch each other, but I’ve had a lot of these systems laying around, in my lap, on a coffee table, even laying on the carpet, while I test.

High Voltage Wiring

This is where you can destroy your equipment, home wiring, start a fire, harm or kill yourself. BE CAREFUL and if you do not understand what you are doing find someone to help. This is something most home brewers will find trivial, but if there’s any doubt; don’t.

  1. Look at the “hot” side of your outlet. On North American outlets with the ground terminal towards the bottom, this will be on the right side of the outlet between the two terminals. These terminals are generally gold. There is a jumper there which you can grab with a pair of pliers and break off. Do so. This allows you to power each outlet separately, one for heat and one for cool. If you do not do this, you will be running your heater and your fridge at the same time and wondering WTH is going on.

    This is called a “split receptacle” or sometimes a “switched receptacle.” When you buy your outlet at the local big box store, the people that work in electrical (if you can ever find one) can point this out for you as well.
  2. Take two lengths of stranded wire, 16-18 gauge and preferably red. These will go between the relays and the outlet so maybe a foot or two long. Some crimp-on terminals (called “spade” connectors) would help here but are not absolutely necessary. If you do not use spade terminals, it would be better to use solid core wire for this part. Connect them one each to the hot terminals on the side of the outlet (where you broke off the jumper.)
  3. Connect the other ends of those wires to the “NO” (this doesn’t mean “don’t do it”, it means “Normally Open”) side of the two terminal blocks on the high-voltage side of the relay board. I’d recommend crimping on what’s called “bootlace ferrules” or tinning the ends of the wire (melting solder on the end) if you are using stranded wire. You can do without the ferrule or tinning for testing, but for production use, it’s highly recommended.
  4. Take a piece of black stranded (tinned or ferrules on the ends) or solid-core wire and run it between the NC (Normally Closed) terminal of relay number one (on the top as you look at the relay board with the high-voltage on the right) and the COM terminal on relay number two. Refer to the diagram above for clarification.
  5. Take your power cord and strip enough of the main insulation to work with the three leads. Strip the tips of the three leads. A spade terminal would be good on the ground (green) and the common/neutral (white) leads. The hot lead (normally black) should get tinned or a ferrule.
  6. Connect the ground to the ground lug on the outlet. Connect the common/neutral lead to the neutral side of the outlet.
  7. Run the hot lead from the power cord to the COM terminal on relay number one.
  8. If you are using a metal box for your outlet, run an additional (preferably green) lead between the ground lug on the outlet to the ground lug on the box.

At this point your high voltage side is complete, at least enough for testing. Test BEFORE you plug in your power cord! I am not responsible for anything that goes wrong here so make sure you know what you are doing or have a licensed electrician do the work or check your work. One outlet is going to be controlled for heat, one for cool. Your (optional) fan can be plugged in any convenient outlet – it should run 100% of the time.

I’d highly recommend you mount the outlet to something that’s not going to move, put it in an outlet box, something to protect you and your belongings from the high voltage terminals.

As one final step before plugging in your refrigerator or heater, grab a couple of cheap outlet testers with lights, or even a couple of table lamps, and test some more to make sure things work like you expect.

Work Complete

The work above, and putting the “guts” into a suitable box, are all I did for my fermentation chambers. I plug my kegerator (set on 100% cold) into the “cool” outlet, and my heater (a 60w lightbulb in a paint can) in the “heat” outlet, and let magic happen.

From here there are many ways to go … 3-D printed cases are getting pretty popular. I’ve also seen folks come up with really nice setups from just a trip to the big-box hardware store. The sky is the limit!

“Hacking a Fridge”

This sort of setup relies on being able to directly turn on and off the compressor on the refrigerator. Normal modern fridges often are “frost free” which is accomplished by using a timer and a small heater on the coils to defrost the tubes. It should be obvious that this would not work well for this application. As described here we use what ends up being a “switched power cord” and leaving the fridge wiring intact. There are MUCH more elaborate ways to do this. One of the best write-ups is on the original BrewPi website under Fridge Hacking Guide.

If you do follow the instructions here, you will need a way to get the wiring for the sensors, heater and fan inside the fridge. These methods range from obvious (a kegerator has a hole on the top for the beer lines which may be used for our purposes) to the exceedingly elaborate (some people drill through the sides and use surface-mount electrical connectors.) If you do drill your fridge, make sure you know where the coolant lines are. Piercing one of these is a one-way ticket to the junkyard.

For the Masochists (or the truly paranoid)

(This article is written for BrewPi Legacy Remix version, it likely applies to other versions but there may be some differences.)

You’re here for one of a few reasons:

  • You’re just curious about how things work
  • You hate easy things and want to do this the most difficult way possible
  • You are exceeding (perhaps justifiably) paranoid and refuse to run scrips as root. Maybe starting at the bottom of this article is a good place to start?
  • You are one of those people that find some twisted satisfaction in running something named BrewPi on something other than a Raspberry Pi

We’re not here to judge (or am I silently judging you right now?), we’re just here to help. Just like the government. Here’s what you have to go through to replicate most of the scripting in the BPR tool set. Note that this only addresses a single-chamber setup. I’m not sure I feel like describing what has to be done to do multi-chamber but a smart person can figure it out from the information that’s out there for the Legacy BrewPi.

Finally before we dig in, these instructions are written for Debian-based Linux distributions (of which Raspbian is one.) If you use something else, chances are you already understand the differences.


The bootstrap especially does some checking which may not specifically be strictly required, but is highly recommended:

  • Check to see if the default password of ‘raspberry’ is still current for the ‘pi’ user. If so, prompt to change it.
  • Prompt to set the proper timezone. Since BrewPi works on schedules and the graph is of course time-based, having the proper system time is important. Yes, I could do some work to allow UTC and display in the user time zone … but why?
  • If the hostname is still ‘raspberrypi’, prompt to change it. More than a few folks have more than one Raspberry Pi, and being able to use a nice name like “brewpi.local” to get to the system is handy. Plus, you should never have two machines with the same name on the same network segment. It confuses anything with an ARP table (like your router.)

APT Repositories

Manipulation of APT repositories is required to support this product. This obviously needs to be done as root, however the repos are GPG signed so in theory there’s an added level of security.

As with any other apt packages, it is always good practice to refresh your local apt indexes before doing any installs, updates, or uninstalls. This command will re-synchronize the package index files from their sources. The indexes of available packages are fetched from the location(s) specified in /etc/apt/sources.list.

sudo apt update

There are some packages known to conflict with the solution as well; namely nginx and anything related to php5. This should not be a surprise since we use apache2 as a web server and nginx is a web server itself. Yes a crafty person can make them coexist, if you’re that crafty you don’t need my tutorials. Some of the packages I suggest to reinstall will be reinstalled again with apache2 and that’s fine. The process may also suggest removing other packages which are included by dependency; remove those as well. To uninstall nginx, use the following command:

sudo apt remove libgd-tools, fcgiwrap, nginx-doc, ssl-cert, fontconfig-config, fonts-dejavu-core, libfontconfig1, libgd3, libjbig0, libnginx-mod-http-auth-pam, libnginx-mod-http-dav-ext, libnginx-mod-http-echo, libnginx-mod-http-geoip, libnginx-mod-http-image-filter, libnginx-mod-http-subs-filter, libnginx-mod-http-upstream-fair, libnginx-mod-http-xslt-filter, libnginx-mod-mail, libnginx-mod-stream, libtiff5, libwebp6, libxpm4, libxslt1.1, nginx, nginx-common, nginx-full

To uninstall php5, I could give you a script but you’re here because you either don’t trust my scripts or you can’t use them for some reason. You can use the following command to find php5 packages which may be installed:

dpkg --get-selections | awk '{ print $1 }' | grep 'php5'

You would have to uninstall each of the returned package names with:

sudo apt remove {package name}

Now you need to install a series of APT repos. Here’s the command you would run to install all repos used in this product:

sudo apt get git arduino-core git-core pastebinit build-essential apache2 libapache2-mod-php php-cli php-common php-cgi php php-mbstring python-dev python-pip python-configobj php-xml

Pip Installs Packages (pip)

In addition to the apt packages, several additional python packages will be necessary. These are installed with pip:

 sudo pip install pyserial psutil simplejson configobj gitpython --upgrade 

User Setup

BrewPi runs as its own (now passwordless) user. Here we create the brewpi user and add it to the dialout, sudo and www-data groups:

useradd brewpi -m -G dialout,sudo,www-data

Next we add the ‘pi’ user (or whatever user you normally use to the www-data and brewpi groups:

usermod -a -G www-data,brewpi pi

Clone git Repositories

There’s four repositories that make up this product:

  • BrewPi-Tools-Remix – The toolset that this article replaces, so we won’t clone it here
  • BrewPi-Script-Remix – The core Python scripts which communicate with the Arduino and website
  • BrewPi-WWW-Remix – The PHP website which forms the user interface
  • BrewPi-Firmware-Remix – This repository does not need to be cloned, one need only download the current compiled firmware

Make sure the /home/brewpi directory exists and is empty. Clone the scripts as the brewpi user with the following command:

sudo -u brewpi git clone -b master --single-branch /home/brewpi

The web root should be /var/www/html but new versions may change that. Clean out that directory (it probably has a default index.html file there) and clone the website as the www-data user with the following command:

sudo -u www-data git clone -b master --single-branch /var/www/html 

Set Permissions

One of the more common solutions to a whole slew of issues is setting the permissions correctly. There is a script for this in:


If you are still needing or wanting to proceed manually, the following commands are issued:

chown -R www-data:www-data /var/www/html
find /var/www/html -type d -exec chmod 2770 {} \;
find /var/www/html -type f -exec chmod 640 {} \;
find /var/www/html/data -type f -exec chmod 660 {} \;
find /var/www/html -type f -name ".json" -exec chmod 660 {} \;
chown -R brewpi:brewpi /home/brewpi
find /home/brewpi -type d -exec chmod 775 {} \;
find /home/brewpi -type f -exec chmod 660 {} \;
find /home/brewpi -type f -regex "..(py|sh)" -exec chmod 770 {} \;
find /home/brewpi/logs -type f -iname "*.txt" -exec chmod 777 {} \;
find /home/brewpi/settings -type f -exec chmod 664 {} \;

Arduino Firmware

You can download the precompiled firmware (sorry, not going to go into how to compile it on your own here) from the GitHub repo. For instance here’s how to download the latest Arduino Uno firmware:

curl -O

You would now flash your connected Arduino with the following command. Be sure to update the port (following the ‘-P’) with the port where your Arduino resides:

avrdude -F -e -p atmega328p -c arduino -b 115200 -P /dev/ttyACM1 -U flash:w:"brewpi-arduino-uno-revC-0_2_10.hex" -C /usr/share/arduino/hardware/tools/avrdude.con

Daemon Unit Files

BrewPi and a checker for the WiFi connection run as a systemd daemon. The following files must be placed in the /etc/systemd/system directory. The first is named brewpi.service and contains the following text:

Description=BrewPi service for: brewpi

ExecStart=/bin/bash /home/brewpi/utils/ -d


Change permissions on the file, enable and start the service with the following commands:

sudo chown root:root /etc/systemd/system/brewpi.service
sudo sudo chmod 0644 /etc/systemd/system/brewpi.service
sudo systemctl daemon-reload
sudo systemctl enable brewpi
sudo systemctl start brewpi

The (optional) WiFi check file should be saved as wificheck.service and it contains:

Description=BrewPi service for: wificheck
ExecStart=/bin/bash /home/brewpi/utils/ -d

And as with the brewpi daemon, set permissions, install and start it with the following commands:

sudo chown root:root /etc/systemd/system/wificheck.service
sudo sudo chmod 0644 /etc/systemd/system/wificheck.service
sudo systemctl daemon-reload
sudo systemctl enable wificheck
sudo systemctl start wificheck

Work Complete & Final Thoughts

In theory, you should now have a working BrewPi Remix running in single chamber mode. I will however leave you with some final thoughts.

If you are one of those folks who got here and followed these instructions out of some sense of increased security by not running my install scripts I’ve got bad news for you. You are still running scripts from some random person on the Internet and some start as root.

With thanks to the folks at, I’m going to paraphrase a few of their sentences:

Using curl|bash or curl|sudo bash certainly seems insecure. To anyone with a basic understanding of Unix, the construction makes it really obvious: This command will give the named web site direct access to your system, with the ability to do anything that you could do. This feels very wrong: We should be able to install software without giving the developers full access to our systems, right?

I would be the first to agree that software you install should not be automatically fully trusted. Unfortunately, however, traditional Unix software is always granted the full authority of the user who runs it (and in the case of a stock Raspbian OS this implies passwordless sudo). When you install software on Linux, no matter what package manager you use, you are giving that software permission to act as you. Most package managers will even execute scripts from the package at install time – as root. So in reality, although curl|bash looks scary, it’s really just laying bare the reality that applies to every popular package manager out there: anything you install can pwn you.

If you wish to install any software without giving it full access to your system, you must install it on a dedicated machine, VM, or (perhaps, with caveats) an isolated user account. In truth it’s more work than a lot of people want to deal with and in my experience people spend a lot more time complaining about it than actually taking steps to be secure.

The reality is this:

  • This is free software and you are invited to not run it if you are that concerned. I’d argue however that even the most paranoid among you have downloaded and run applications from the Internet with no additional security. At best, maybe you scanned it for viruses, but I’d be willing to bet a normal home user would not perform a source-code scan. If you are a person who really does a source-code scan, this is all written in bash, PHP, Python and the firmware in a proprietary C-ish language. It’s all there and all able to be downloaded freely and handled however you wish under the terms of the GNU General Public License.
  • This is intended to be run on dedicated hardware. A Raspberry Pi is really perfect for this and a Pi Zero W is about $20. There’s no reason to try to run this on some other rig on which you do other things that could be compromised by rogue code.
  • The last significant vector at risk here is the network to which the BrewPi machine is attached. If you have IoT devices, surely you have a separate wireless LAN segment for them? Put this there. Tom has a great article about IoT security. You can also choose to not have your BrewPi connected to your home network at all. Sure you lose some functionality, but you can always disconnect the network and just use it with a local keyboard, mouse and monitor.

I’m not making fun of people displaying a healthy dose of paranoia. At last count I am tracking 552 website credential pairs, all using unique highly complex passwords. Yes that’s right, I have over 500 passwords to keep track of. In addition I use two-factor whenever possible. Believe me when I say I am a fan of security. Sometimes though you gotta pick your fights and mitigate risk when you do.

One last word: As a fan of security I do have several ideas how to make this application more secure. I don’t have a schedule and nobody is paying for this so who knows what I’ll get done. Stay tuned though, surely the battle will be won in small skirmishes.

Security Note

My instructions tell you to copy and paste a command into your terminal window. Despite me telling you to do that, I am now going to tell you how unsafe that is. Many people browse the Internet, find the command they need, and blindly paste it into their terminal window. This one is blatantly (potentially) dangerous from a non-trusted source:

wget -qO- | sudo bash

It’s going to download a script to your Raspberry Pi, and pipe (|) it through the command sudo bash. When you use sudo without any other arguments it will run the command which follows with root privileges. So, you basically found someone on the Internet telling you to run their code as root, without even knowing what it all does. Despite the inherent risk, installing an application as root is often necessary since some applications have to make global changes to your system.

This is how bad things happen.

Even if you think you completely understand the command you are reading and copying, there is still an opportunity for a specially crafted web page to make the command look like one thing, but be a completely different command when you paste it. That would be A Bad Thing™. For an example, copy and paste this code into your terminal (or if you are now suitable paranoid, into a text editor:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!
Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwd
git clone

(From this page which describes this copy/paste vulnerability.)

The lesson to be learned from this is if you are going to copy/paste a command from any source, always use an interim paste into a text editor like Notepad to make sure A Bad Thing doesn’t happen to you. Now you can join your previously scheduled show: Install Instructions, which is patiently waiting for you where you left it.

Wait. Now you don’t know if you should trust the setup command I provided? I’m shedding a happy tear. Security and the Internet is a rabbit hole filled with (justifiable) paranoia and bad actors. Your choices here however are:

  1. Trust me and run it
  2. Examine that script carefully and make sure it does nothing bad. Then, since the first one executes as root you need to follow that to the next one because it inherits that security construct. Ultimately you can drive yourself crazy when you realize the implications, or just accept that whenever you install free code from the Internet you take your chances. This is the case with any software, not just BrewPi.
  3. Do a manual install. I’ve detailed how that might be done in a post called: “For the Masochists.”

At some point I hope to list out the manual install steps necessary to replicate this series of automated steps for the truly paranoid. That’s quite frankly not a high priority for me since the goal here is to make BrewPi Legacy Remix available to every-day people. Those of you who would choose the manual steps can probably figure it all out anyway.


Return to the Installation Instructions.

Project Assumptions and Proceedings

This tool set adds a bootstrap to install the BrewPi Legacy Remix packages on a completely fresh install of Raspbian (codename “Stretch” at the time of this writing). I have created this bootstrap because some steps required in previous iterations were a little alien to people new to Raspbian/Linux. Additionally, some supporting software has been deprecated/upgraded which before now made the older BrewPi packages incompatible.

This bootstrap will:

  • Check a few things
  • Handle some Raspberry Pi setup steps if/as needed or recommended
  • Install some supporting files
  • Download and execute the BrewPi-Tools-RMX installation scripts
  • Perform some final cleanup

In order to make this work well, I have to make some assumptions about the environment in which this will be run. Here I’ll try to list some, however I am sure someone will find a way to try something I’ve not considered. Do not over-think this. Don’t fiddle around with your Pi before running the bootstrap. Turn it on, connect to your home network, and go. Here’s a list of known (or at least recalled) assumptions made during this project:

  • This has been developed and tested on a Raspberry Pi 3 B+ because that’s what I have laying around. I have absolutely no reason to believe it would not work on a Zero, 2B, or other versions of the Raspberry Pi line. I’ve just not tested it.
  • This has been developed and tested on the Raspbian OS. Raspbian is based on Debian, so using a Debian (or derivative) OS distribution may work. However, that’s not been tested. I am not at all sure that it would work on a different flavor of Linux.
  • This has been developed and tested on the Raspbian Stretch distribution. If a new distribution for the Raspberry Pi is released it may no longer work. I hope I’ve future-proofed it, however the original/core code may have some non future-proofed areas waiting to rear their ugly head (or I may not be as good at future-proofing as I believe.)
  • I’ve assumed throughout that this is the only function the Pi will handle. This is not unique to BrewPi in general. I’ve not specifically prevented it form doing anything else, I just can’t (and won’t try) to test every permutation.
  • This will not create a BrewPi which is secure enough to connect to from the Internet. There’s a whole host of reasons for this, but please, do not do it unless you know what you are doing. I suggest you consider Dataplicity if you really need/want to do this.
  • This has been developed and tested using the default user ‘pi’ which by default has password-less sudo rights. This is how Raspbian is shipped, and this is how I’ll continue to test it. If you know enough to change any of these assumptions, you know enough to figure out why this process may not work for you. If you simply MUST change this, I suggest you do it after you get BrewPi Remix running.
  • You need for your Pi to have access to the Internet. I think this is obvious, but the Pi needs to access GitHub and standard Raspbian repositories to download code. Generally speaking, plugging your Pi into your home network with an Ethernet cable will do this without any configuration necessary. Attaching to wireless will take a little more work that’s not in scope of this project specifically, but for which you will find some help in “Headless Raspberry Pi“.
  • This has been developed and tested on a bone-stock Raspbian setup, with no user or local customization implemented. The only things that has been tested which do not inherently work on a fresh setup is wireless connectivity and ssh over wireless. The bootstrap script will:
    1. Check to make sure the script has executed with sudo to root (this is how the instructions will work if you follow them)
    2. Provide some rudimentary instructions
    3. Check for default password, and prompt to change it if so
    4. Set the proper timezone
    5. Prompt to optionally change the host name if it is currently the default ‘raspberrypi’
    6. Check network connectivity to GitHub (this part should be a given since it’s intended to be run via wget but I’m not going to assume someone can’t break my plans)
    7. Run an apt update if it’s not been run within the last week
    8. Install git packages via apt get to allow the rest of the install to work
    9. Install Python packages via pip.
    10. Clone the BrewPi Tools RMX into the ~/brewpi-tools-rmx folder
    11. Execute which is responsible for the rest of the setup

I am certain that someone will find an important assumption I did not list here. We’ll see how long that takes. Let me know what you find.

Return to Installation Instructions.

BrewPi Remix Install

This is my fork of the original BrewPi Project. If you are looking for the original, please click here.

BrewPi Legacy Remix runs on a Raspberry Pi, communicating with an Arduino. Despite the original creators no longer actively supporting BrewPi on Arduino, and despite the Arduino being arguably one of the least capable controllers on the market, BrewPi on Arduino still has an amazing following among home brewers. When I last checked there were 7473 posts in this thread on since March 19, 2014 when @FuzzeWuzze started the thread.

Before we proceed, a huge thank you to Elco Jacobs, without whom none of this would be possible.

Please also check Assumptions and Proceedings before continuing if you are not starting with a bone-stock fresh install of Raspbian on your Raspberry Pi.

To begin installing BrewPi, you need only issue the following command in a terminal window or via ssh on your Internet-connected Raspberry Pi:

curl -L | sudo bash

or the underlying link:

curl -L | sudo bash

Both of these are the same, I just created a short URL to make it easier for you. Some folks prefer not to be redirected, so the regular link is there as well

If you have a broken installation and/or need to run the uninstaller without BrewPi being installed correctly for some reason, you may use:

curl -L | sudo bash

If you’d like even more, here’s a YouTube video showing the entire process on version 0.5.1:

If you have questions, please read the FAQ.

Step by step instructions, with descriptions of each step, are being developed. I do however think each step has enough instructions to get the average person going if you just slow down and read them.

If you hate the idea of doing something the easy way, or if you for some reason need to install manually, see my post: “For the Masochists.”

Known issues

You can view or log new issues via the links below (when in doubt, just use the first link):

NameKnown Issues
Install and uninstall toolsIssues List
Python scripts supporting BrewPi
Issues List
Website filesIssues List
Arduino firmwareIssues List

Headless Raspberry Pi

Note: If you are here for instructions related to the “Headless Pi” application for preparing SD cards, you can skip down to that section.

What is “headless?” A headless computer that has been configured to operate without a keyboard, monitor and mouse. If you are a typical home computer user, you might wonder how this is possible, and why a person would want to do that.

Well, the Raspberry Pi is unique in it’s form factor. A fairly standard case creates a package that’s a whopping 5.5 x 5.1 x 1.4 inches. I have old rollerball mice that are larger than that. Something of this size is perfect for many applications and projects including media centers and console gaming. But, if you have to add a monitor, mouse and keyboard; it’s no longer so small and unobtrusive. Some people have been very creative with cases for the Pi; one person even put a Raspberry Pi Zero in a Tic Tac® box.

A Raspberry Pi Zero in a Tic Tac® case

There is no need to have a monitor, mouse and keyboard plugged into the Raspberry Pi; it can be operated quite easily and effectively as a headless system. In days past, large Unix systems sat in a room the end user would never hope to see, and they were accessed from a terminal like this one:

The DEC VT100, a widely emulated computer terminal

That’s pretty sexy, right? I’d actually love to have one of those as a conversation piece.

Seasoned users of Unix/Linux/variants use a program called a terminal emulator to access their servers from their workstations. The most well known (and FREE) terminal emulator for Windows users is PuTTY. It allows you to access your Raspberry Pi over the network, in a secure fashion, without needing to tear apart your gaming rig for a monitor, mouse or keyboard.

I can hear you thinking right about now: “But I don’t know how to type all those commands and stuff, I’m not a Unix person!” Fear not. I led you here, sir, for I am Spartacus. I can step ANYONE through this. Still don’t believe me? How about if I tell you that you can use a graphical interface on your Raspberry Pi instead while still on a headless Raspberry Pi? Graphical application access is done using what’s called the X window (not “Windows”) system – and is available over the network. More geekery that you don’t understand? I will make it easy for you to understand.

A modern example of a graphical user interface using X11 and KDE

I can see now you want to believe. When I am done you WILL believe.

The only physical connection that is absolutely required for your Raspberry Pi is power. Everything else is optional and we will do without any of that needless clutter. Let’s get started!

Required Hardware

You don’t need much to get started, and it’s not going to be very expensive. Here are some recommendations:

  • A Raspberry Pi bare board – I recommend the new Raspberry Pi 3 B+ unless you already have one laying around.
  • A suitable power supply – The CanaKit 2.5A Raspberry Pi 3 B+ Power Supply with PiSwitch is a good one. Many old phone chargers will work after a fashion, but they are often not capable of delivering the full power without a voltage drop. This can cause unexpected reboots and sometimes SD card corruption. Do NOT use a power switch like this (or heavens forbid unplug your Pi) without issuing the system a shutdown command. You have been warned.
  • A good micro SD card – You will only need a 4GB card if you are doing this for a BrewPi and will not use a graphical interface. I recommend at least an 8GB card if you will use the full Raspbian distribution. You want one from a reputable manufacturer rated as Class 10 UHS 1. They are getting so cheap now, there’s few reasons not to get a larger one like this Samsung 32GB. This one also comes with a standard SD card adapter which will allow you to directly plug it in many computers with a standard SD Card slot.
  • An SD USB adapter – If your computer does not have an SD Card slot, you will need a way to connect your SD card to your computer. I have and like this Rocketek Aluminum USB 3.0 Portable Memory Card Reader Adapter for Micro SD Card. It’s small, and it’s aluminum which helps it to dissipate heat (these things heat up when writing.)
  • (Optional) A Case for your Raspberry PI – When we say “bare board” that’s exactly what we mean. A case is almost a must-have, but some people get very creative (like the Tic Tac® box shown above) or whatever they have laying around. I actually came up blank when looking for a “entry-level” case for the Pi 3 B+. As you shop, just be aware there are differences between the boards, and you need to get the right one for the board you have/are buying.

If you don’t have any of the above and you are just looking for a kit to get you started, CanaKit sells the Raspberry Pi 3 B+ Starter Kit for $79.99, which includes:

  • Made in UK Raspberry Pi 3 B+
  • 32 GB Samsung EVO+ Micro SD Card (Class 10)
  • 2.5A Raspberry Pi 3 B+ Power Supply with PiSwitch
  • Raspberry Pi 3 B+ Case
  • HDMI Cable
  • 2 x Heat Sinks

Want to start even smaller? The Raspberry Pi Zero W is a single-processor (versus the 3 B+ having a quad-core processor) WiFi-enabled board that’s perfect if you just want to dip the tip of your big toe in. Amazon has the CanaKit Raspberry Pi Zero W (Wireless) Complete Starter Kit – 16 GB Edition for $32.99 which includes a case, SD card, power supply, everything you need to get going.

Aside from my expectation that you have a computer to start with (you are reading this somehow), and that you either have wireless (preferred) or wired Ethernet available; that’s really it.

Required Software

The software you will need comes in two types: software for your current computer which I will call “client;” and the OS for your Raspberry Pi which from now on we’ll call “server.”

Client Software

There’s two required software packages you will need, and one optional. I am listing Windows versions of these tools because that’s what I am using. If you use a Mac you are already used to figuring out some things on your own. Sorry, but you’re probably better at it than I am. Here’s your shopping list:

  • PuTTY – Terminal Emulator – You will use this to communicate with and control (at least at first) your new Raspberry Pi. Download it from the author’s website and install it on your PC. There are other Terminal Emulators, but I’m not going to go into them because this one really is the de facto standard as far as I’m concerned. There are a lot of different packages listed on that page. Up top, it says “MSI (‘Windows Installer’)”, grab one of those. If you don’t know if you need 32 or 64-bit, just grab 32-bit. For our purposes, there are no differences.
  • SD Card Writer – Here I’ll list a few choices;
    • Raspberry Pi Imager – My new preferred imaging solution for a Raspberry Pi. Well-integrated into the Raspberry Pi ecosystem, as a product from should be. No need to download the OS image separately when using this product.
    • balenaEtcher – A very well-thought-out program and easy to use. The tutorial will be written following the process for this piece of software. Optionally, you can use:
    • Win 32 Disk Imager – This is an older program and not as fully-featured. It also has some “quirks” to its use. Between the two, however, it’s the one which you can use to back up your SD card later on. I suggest even if you want to do this (and there are good reasons to do so,) that you start with balenaEtcher for your first go at it.
  • (optional) RealVNC Viewer – Connects to the Raspberry Pi to use a graphical interface.

Download and install PuTTY, Raspberry Pi Imager, and (optionally) VNC Viewer and we can move on.

Server Image

This is written around the Raspbian OS. Just like there are different versions of Windows 10 (Home, Pro, Enterprise), there are different versions of Raspbian. The current release is called “Buster” and the Raspbian Buster distributions are based on Debian Linux 10 (Buster). Three different flavors of Raspbian Buster are available for the Raspberry Pi. All are available from the same download page.

Note: If you are using the Raspberry Pi Imager, you can skip this step and head down to Software Installation and Configuration.

Your choices on the image download page will be

  • Raspbian Buster Full – Stretch with a full-featured desktop interface and a handful of applications you may be interested in. If you will be using your Pi for something other than just BrewPi for instance, or just want to play around, you can start with this. It’s a little over 5GB so you will want a larger SD card with this one. I recommend at least 8GB and chances are you will want more.
  • Raspbian Buster with desktop – Same PIXEL desktop with less ancillary applications. I’ve never actually figured out the differences because I never use a graphical desktop. It’s a little over 3GB in size so you can use a smaller card.
  • Raspbian Buster Lite – The slimmest of all the distributions at just under 2GB. I use this distribution effectively even on my 4GB cards. You do not need a graphical interface to run the BrewPi server

Unless you know what “Torrent” is, chose the “Download Zip” option for the package you chose.

Get one of these downloaded and we’ll get going. To follow this to the end and use a graphical interface, you will want either the “Raspbian with Desktop” or “Full.” Honestly, I rarely use a graphical desktop anymore since it consumes resources and I don’t ever actually work on the Raspberry Pi (I use it as a web server most often.) You take care of your needs and I’ll get you there.

Software Installation and Configuration

So now you have your Raspbian image, you have PuTTY and Raspberry Pi Imager (and probably VNC Viewer) installed, right? You are as prepared as you will get, might as well jump in before you chicken out.

Addundum for RPi Disk Imager

Since writing this article, the Raspberry Pi Imager has released support to set the following items:

  • Hostname
  • Enable SSH
  • Change password
  • Configure Wifi
  • Set locale

Simply hold down Shit + Control and press the “X” key to view this menu. I have NO idea why this is not more prominently featured.

Create the Boot Media

Go ahead and execute Raspberry Pi Imager You are presented with a window that should look a lot like this one:

Raspberry Pi Imager at startup

There’s not a lot of options here, which is good:

  • Step 1: Operating System – Choose OS – Here you will select your preferred flavor. I recommend the first selection; Raspbian. You are free to choose Raspbian (other) and select between Full and Lite.
  • Step 2: SD Card – Choose SD Card – If your SD card is not plugged in, go ahead and plug it in now. You may see a pop-up about the card not being formatted (here and further in the instructions.) In all cases just hit “Cancel” and move on. You will see that unless you have more than one drive the software will just select it for you. You can change the selection if you really do have more than one plugged in, or go to the next step.
Example Pop-Up during process
  • Step 3: Write – Really, that’s it. The software will go through, flash the drive and then verify it. You may hear some “dings” from your computer as the new drive(s) are detected and mounted. You will likely see those pop-ups again. Just hit “Cancel” if they do pop up and wait for the process to be complete.
Raspberry Pi Imager during the SD write process

When writing the drive has been completed, you will see a window like this:

Writing Complete.

It is safe at this point to eject/remove the SD card. If you are hell-bent on not going headless, you are done. Plug the SD card into your Raspberry Pi connected to a keyboard, monitor and mouse, and plug it in. If you really want to hang out with the cool kids, keep reading ….

Configure the Boot Media

(This is deprecated since updating the imaging tool. See: Addundum for RPi Disk Imager above.

The SD card is in your hand, plug it right back into your computer again. Again you will likely see a pop-up about an unformatted drive, again hit “Cancel” and move on. (If you did not remove and re-insert the card, you need to do so now.)

At this point, you may open Windows File Explorer. This is informational only, you need not do anything yet.

In the list of drives on the left (you may have to scroll down, and/or expand the choices under “This PC”, you sill see two additional drives called “USB Drive” and “boot.” The drive letters may be different but you definitely want to select the one named “boot.” This is one of the two partitions created on the SD card; “boot” is an MS-DOS type partition and “USB Drive” shows as unformatted but is actually a Linux partition.

Files in the ‘boot’ Partition of a Raspbian SD Card

Within the “boot” partition (here the E: drive, may be different on your computer), you are going to create two files in a little bit:

  • ssh – A file with no file extension named “ssh.” It can be and should be left empty. It gets deleted during the first boot process. It serves to tell Raspbian to turn configure the ssh daemon (similar to a Windows service) which is how we will connect.
  • wpa-supplicant.conf – This one is semi-optional. If you are using an actual Ethernet cable then it’s not needed at all. If you plan to use WiFi it’s less optional. It will contain the configuration for your wireless networking, allowing Raspbian to connect on first boot.

Now, referring to the window up there, note that some of the files have extensions of “.dtb” and “.bin.” Windows, by default, hides file extensions for files it thinks it knows like text files (*.txt) and Microsoft Word documents (*.doc). There’s a couple ways to go about creating these two files we need, one of which has no extension at all and one of which has an extension of .conf. There’s more than a few ways to do this, I’ll give you a couple:

There are two ways to proceed now. Either choose the easy way, immediately below or the hard way further down the page.

The Easy Way – Using “Headless Pi”

I created a small application which will help you with this. You may download it here (for free of course):

  • Headless Pi – A Windows application to assist setting up a new Raspberry Pi SD card for headless operation.
  • Headless Pi Source Code – Visual Basic 2017 project released under the GNU GPL (you only need this if you would like to compile the above file for yourself).

With your SD card inserted, go ahead and execute the Headless Pi executable. If you have issues, check the release page for an installer-based version. It should run without installation on current versions of Windows. There are only a couple ways to mess this up:

No card inserted – You will see this error if you have not inserted a Raspberry Pi SD card. If you just finished writing the card, you forgot to pull it out and re-insert it. Do so, then re-run the application:

No Card Detected

Multiple cards detected – You will see this error if you have more than one Raspberry Pi SD card inserted. Remove all but one and re-run the application:

Multiple Cards Detected

When you execute the program it will auto-detect your SD card. Look at the “Target Device” label towards the bottom and visually verify that this is correct. This program should err on the side of safety, but this is free software and you get what you pay for so this one is on you.

After you have verified the application is pointing towards the correct mount point, you have two items to configure:

Headless Pi UI Screen
  • SSH – This is a checkbox to enable (or not) SSH on the Raspberry Pi. When you check the box the application will write a file named “ssh” on the /boot partition which enables ssh on first boot. When you un-check the box, this file will be removed. Unless you don’t need ssh (and if that’s the case I have no idea why you are reading this) you will want to check this.
  • On the Go – This checkbox will enable configuration for On The Go (OTG) functionality. This allows a Raspberry Pi Zero or Zero W to be configured as an Ethernet device. It connects to (and is powered by) the host system, using the host’s networking. More details can be found here.
  • Wireless – When you check this box the remaining configuration items will become enabled. You need to configure the following:
    • Country Code – Select the proper country code for where you live. For instance, if you are in the US, scroll down to “United States” or begin typing your country name and the list will scroll.
    • SSID – This stands for “Service Set Identifier” and is the name of your wireless network. This must be typed correctly in order for it to work so be double sure it is correct. The SSID is a case-sensitive text string that can be as long as 32 characters consisting of letters and/or numbers. Within those rules, the SSID can say anything. You will need to refer to your wireless router manufacturer or broadband provider for this information.
    • Password – Your wireless network password, obviously if this is not correct you will not connect. The password is not blanked out so you will be able to verify it as you type.
    • Known Networks (new in 3.1.0) – This box will list locally configured wireless networks, and if it is able, to populate the UI with that information to save you some typing (and possible mistakes.)
  • Write Supplicant File – Once you have these four fields filled out and you are sure they are correct, the “Write Supplicant File” button will be enabled. Clicking this button will write out a properly formatted wpa_supplicant.conf file to your SD card. Clicking multiple times will simply overwrite the file so if you make a mistake you can correct it and try again. If you un-check the box again it will remove the file.

If you use the “Eject and Exit” button, the program will attempt to eject the USB card programmatically so you may safely remove it. If you do not with to do this, use the red “X” on the top-right corner. If you do that, be sure to use the Windows controls to eject the card before you remove it to prevent corruption.

The Hard Way – Using “Notepad++”

You can download the free program “Notepad++” which is a replacement for the Windows Notepad. It is quite a bit more capable however. I won’t review anything other than what you will need to know in order to get through this particular set of instructions, but a little review of it will probably result in you never using Windows Notepad ever again.

Go ahead and start up Notepad++ and close the first tab you see which is the changelog for the current version. Then, change the end of line (EOL) type to “Unix” by selecting Edit > EOL Conversion > Unix (LF).

Change File Type to Unix

Since you are currently looking at a blank file, and the “ssh” file does not need anything in it. select File > Save As> and navigate to the SD card’s boot partition. For a name use ssh. (notice the trailing period, this is critical) and click “Save.”

Save ‘ssh’ File

Next, you can paste in the following text as a start point for your wpa_supplicant.conf file:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev


Change the following items to values appropriate for your use:

  • Country – Change the country code to the proper two-letter code for your country. You can find a list of country codes here.
  • SSID – This stands for “Service Set Identifier” and is the name of your wireless network. This must be typed correctly in order for it to work so be double sure it is correct. The SSID is a case-sensitive text string that can be as long as 32 characters consisting of letters and/or numbers. Within those rules, the SSID can say anything. You will need to refer to your wireless router manufacturer or broadband provider for this information.
  • PSK – Your wireless network password, obviously if this is not correct you will not connect.

Be sure that you retain the double-quote mark around SID and PSK. There should be no spaces between the keywords, the equals sign, and the value. Go ahead and File > Save As and save the file as “wpa_supplicant.conf” to the same place as you saved the “ssh” file.

Save ‘wpa_supplicant.conf’ File

Eject Media

Whenever you remove any USB storage, you should always eject it when you are finished. This allows Windows to flush any write cache and close any files it has open. Failing to do this will eventually result in a corrupt device.

To do this, look over in your system tray (the right side of your start bar where the clock is) and look for the USB device icon. Generally you will have to hit the little up arrow (^) to see it.

USB Control Icon

Click on the icon, and select the line that allows you to eject the card reader.

Eject Card Reader

At this point you have your SD card in your hand, all prepped, and ready to go.

Start It Up

At this point you should insert the SD card into your Raspberry Pi, and go ahead and start it up. If you have done things correctly, it will show up on the network and allow you to connect via SSH.

First-Time Connect

Now that your Raspberry Pi is sitting there with it’s little LEDs lit up, it really is doing something. We’ll now go ahead and connect via PuTTY which you should already have downloaded. Go ahead and start up PuTTY and you will see something like the following:

PuTTY Opening Screen

Type in the name of the computer to which you will connect in the “Host Name” field. Since this is the first time you are touching your Pi, the hostname is “raspberrypi.” Follow that with “.local” so that your computer will know how to find it. Optionally, you can prepend the hostname with the username you wish to use. A Raspberry Pi only has one user by default, named “pi.” So, the full entry in the “Host Name” field will be “pi@raspberrypi.local”.

You may optionally give your connection settings a name by typing that name in the “Saved Sessions” box, then clicking “Save.” When you are ready click “Open” to make your first connection. Since this is the first time you will have connected to your Pi, PuTTY will complain that it does not recognize the SSH key. This is a safety item; once saved the first time PuTTY will compare the saved key to the key the server presents in order to make sure your connection is not hijacked by some bad actor. (A bad actor in this context is “anyone on the Internet who means to do you harm”, not a reference to Keanu Reaves.)

PuTTY Security Alert

If you read the very scary text, it will tell you the only safe choice is to “Cancel.” If you hit cancel, you will for sure be safe, but you will also not connect. This first time go ahead and hit “Yes” and the new key will be entered into the system to be checked against next time. Do that, and PuTTY will connect and show you the terminal window.

When presented with the login screen enter the username “pi” (if you did not put the username in the connection string) and then the password. The default password for Raspbian is “raspberry”. If you have followed along correctly, you’ll now be looking at the prompt, logged into your new Pi. The future is looking bright!

Raspberry Pi Initial Login Screen

Optional – Enable RealVNC (graphical) Access

If you selected one of the desktop distributions (anything but “lite”) you can now enable RealVNC access to the Raspbian Desktop. To do this, enter:

sudo raspi-config

Go to “Interfacing Options” > “VNC” > When presented with the question “Would you like the VNC server to be enabled?” select “Yes“. At this point you may or may not need to actually start the daemon (Linux-speak for a service). You can do that now and it won’t hurt if it’s already running:

sudo systemctl start vncserver-x11-serviced

I should point out here that there actually needs to be a desktop running, even if you are not using it (like, no monitor plugged in.) If you are not sure about this, get back in Raspberry Pi Config:

sudo raspi-config

Select: “Boot Options” > “Desktop / CLI” > “Desktop Autologin” or “Desktop” (which will prompt for a login.) This change requires a reboot most often, so go ahead and do so just to be sure:

sudo reboot

Now, go ahead and run the local copy of RealVNC Viewer you downloaded and installed previously (probably just called “VNC Viewer” on your computer).

RealVNC Viewer Window

On the top of the window in the address bar, enter the host name to which we will connect. Just as with the PuTTY connection, use the name raspberrypi.local and hit “enter.” You will see a security notification if this is the first time you have tried to connect to the Pi:

VNC Server Not Recognized Pop-Up

On the chance you are following this tutorial after having gone through it before, you may see an even more scary pop-up because the signature of your new pi will not match the signature of “raspberrypi” from the last time. You can accept that and continue past if you know that to be the case.

Next, you will be presented with the Authentication prompt. Enter “pi” as your username, and the default “raspberry” for the password. Optionally, you can check the box to remember the password. When you hit “Ok” you should see the new desktop.

Authentication Pop-Up

If you see a black box telling you that “Cannot currently show the desktop”, it means that you need to enable the desktop as detailed a few blocks above.

On your first connect if you had not previously changed the password via SSH, you will de a warning that you have SSH enabled and the default Pi password. At some point you will want to change this. If you are reading this for a BrewPi setup, no need to worry about that right now.

Raspberry Pi Desktop

When you clear that screen, again, if this is your first time, you will see a prompt to set some additional items up.

Initial Setup Screen

Here you may choose to go through the setup screens, or if you will be moving on to install BrewPi for instance you can close the window. If you do go through these screens, you will be guided through setup for:

  • Localization settings
  • Changing default Password
  • Wireless setup
  • Updating software
  • Reboot

Be careful about the wireless setup which it will attempt to take you though. If you mess it up, and if you are only connected via the network, you will lose control of your Pi and have to start over (or go find a keyboard, monitor and mouse to connect.)

Work Complete

You’re done! I told you this was not going to be hard. It takes way longer to read these instructions than it takes to implement them.

Setting up Raspberry Pi (Stretch)

Note:  This page is largely deprecated, but I am leaving it here just in case.  To get BrewPi running now, follow these two pages:

  • Off With Her Head! – Headless Raspberry Pi setup.  You can just follow along and skip the wpa_supplicant.conf and .ssh setup if you don’t care about headless operation.
  • BrewPi Remix Install – Instructions to set up the new remix of BrewPi which supports contemporary Raspbian versions.

These instructions were created for the new Raspbian Stretch image. They assume intermediate knowledge of your chosen home computing system, as well as familiarity with using SSH and other networking tools.  These instructions assume a “headless” operation – that no monitor, keyboard, or mouse are needed.

These are the general steps I follow when preparing a new Raspberry Pi image for use with BrewPi (these are specifically deprecated. See the headless setup section in Off With Her Head! The sections below which are struck through may be skipped after following the instructions on that page.)

  • Download your new Raspbian image: (get the full version if this is your first time, not the “Lite” one)
  • Install the image on your SD card:
  • While the SD Card is still connected to your computer, configure the image for headless operation:
    • Locate the /Boot/ partition on the SD Card.  In Windows this will be a new drive letter with the volume name “boot (X:)” where “X” is the new drive letter.
    • Create a new file in the root of this drive named “ssh” (no extension.)   This will enable SSH so that you can connect to the RaspberryPi immediately upon first boot.
    • Create a file called “wpa_supplicant.conf” on the root of the boot partition of the SD card.  In it, place the following information:

Replace “SSID” with the SSID of your local wireless network (leave it in quotes), and “PASSWORD” with your wireless network (leave it in quotes also) .  This will connect your Raspberry Pi to your wireless network automatically upon startup so double-check the SSID and password.

NOTE:  If you do not have Windows Explorer configured to show file extensions, it is possible to have a hidden “.txt” or other extension on the files.

  • Insert the SD card and boot.  Your Raspberry Pi should now be accessible on the network via PuTTY.
  • Use PuTTY to SSH to “raspberrypi.local” with the username “pi” and password “raspberry”.

NOTE:  If you receive an error stating that the host could not be found, it may be that Bonjour services are not installed on your local computer (assuming you use Windows.)  You can obtain Bonjour either by installing iTunes or with the stand-alone installer found here. Bonjour also enables accessing the BrewPi web page with  “{servername}.local” without having to apply a static IP or remember an IP address.  If you use Linux you will need libavahi; under Mac, Bonjour should be installed with the base OS.

  • Enter the command “sudo raspi-config” to execute Raspbian configuration as the root user.
  • Complete configuration:
    • Immediately “Change User Password” to a secure one.
    • Change “Hostname” (I suggest: “brewpi”, this will be assumed through all documentation on this site.)
    • “Localisation Options”
      • “Change Timezone” to proper timezone for your area.
      • “Change Wi-Fi Country” to proper country fr your area.
  • Select <Finish> and reboot.
  • After the Pi reboots, SSH to “brewpi.local” with the username “pi” and password you set previously.
  • Issue the following commands to ensure your software is up to date:
sudo apt-get update && sudo apt-get upgrade -y
  • Issue the following commands to clean local repositories, deleting space used by downloaded archives:
sudo apt-get clean && sudo apt-get autoclean
  • Issue the following command to update the firmware of your Raspberry Pi:
sudo PRUNE_MODULES=1 RPI_REBOOT=1 rpi-update

If the command updated your firmware it will reboot automatically. If not; go ahead and reboot anyway with:

sudo reboot

That’s it!