Fighting Impostor Syndrome With Twilio Internet of Things
Tags: hardware, python, raspberrypi, twilio
Published: 2019-09-11 15:07:57

If you’re reading this, you’ve probably grappled with *impostor syndrome* at one time or another.

Experience doesn’t always help, either. As our skills grow, we tackle harder problems. Technologists are always working at the edge of our knowledge.

What can we do to fight impostor syndrome? [Studies](https://science.sciencemag.org/content/324/5925/400) [have](https://psycnet.apa.org/buy/1999-05981-008) shown that self-affirmation can counteract negative ruminations and increase achievement.  So I decided to build an Internet of Things button that delivers an SMS affirmation when pressed.

# Physical responses to negative thoughts

This project *could* totally be a web application. But – taking a physical action in response to negative thoughts helps ground me emotionally.

Using SMS lets me receive the affirmation without the cognitive load of opening another browser tab. Twilio’s IoT capabilities let me take the button anywhere with cell service. No WiFi configuration required!

The imposter syndrome button was my first hardware project. It was a bit challenging at times. However, with support from my community, I managed to get it working eventually.

I’m excited to walk you through this build – there’s no hardware experience required to follow along.

![A wooden box with a blue button on the top sits on a table. The box has turquoise, teal, and neon yellow stripes and a finger is pointing at the button.](https://thepracticaldev.s3.amazonaws.com/i/voph28ak8unjpgzjqtyj.png)

# IoT Imposter Syndrome Button: Prerequisites

- Raspberry Pi. I used a [Pi 3 Model B](https://www.amazon.com/Raspberry-Pi-MS-004-00000024-Model-Board/dp/B01LPLPBS8/ref=asc_df_B01LPLPBS8/?tag=hyprod-20&linkCode=df0&hvadid=309776868400&hvpos=1o1&hvnetw=g&hvrand=7734478872597576947&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1014221&hvtargid=pla-521496176766&psc=1), but any version later than 1 Model B+ should work
- [LTE Cat 1 Pi HAT](http://wiki.seeedstudio.com/LTE_Cat_1_Pi_HAT/)
- [A button](https://www.adafruit.com/product/3490) with [these wires](https://www.adafruit.com/product/3835)
- [Twilio SIM card](https://www.twilio.com/docs/wireless/tutorials/how-to-order-and-register-your-first-sim)
- Twilio account - [sign up for a free one here](https://www.twilio.com/try-twilio)
- [SD card](https://www.amazon.com/LoveRPi-Raspbian-MicroSD-Raspberry-8GB/dp/B017JKJEAU/ref=sr_1_1_sspa?keywords=micro+sd+card+8gb&qid=1566430576&s=electronics&sr=1-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExWDNERDkxQ0tLS1VTJmVuY3J5cHRlZElkPUEwOTQzOTMzMUdKWTBVTFZSRTRZWCZlbmNyeXB0ZWRBZElkPUEwODIyMDEzM0hFN0VNMkE4RzdGWiZ3aWRnZXROYW1lPXNwX2F0ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU=)
- USB to Ethernet adapter. Make and model depends on what kind of USB ports your laptop has. We had good results using [this model](https://www.amazon.com/UGREEN-Network-Ethernet-Supports-Nintendo/dp/B00MYTSN18)
- (optional) buy or make a box to encase the project

# Getting Started with Twilio IoT

First, [register your Twilio SIM card](https://www.twilio.com/docs/wireless/tutorials/how-to-order-and-register-your-first-sim). Then [create a rate plan](https://www.twilio.com/docs/wireless/understanding-rate-plans). Finally, [buy a Twilio phone number](https://support.twilio.com/hc/en-us/articles/223135247-How-to-Search-for-and-Buy-a-Twilio-Phone-Number-from-Console?_ga=2.57799594.165981211.1567527711-353167408.1558472252) with SMS capability.

Now, we’re going to set up the Pi’s operating system. We’re using a [special Raspbian disk image](https://iot-cdn.twilio.com/images/broadband_developer_kit/alfa/1.1.0/2019-04-08-raspbian-stretch-lite-v1_1_0.zip?_ga=2.57799594.165981211.1567527711-353167408.1558472252) that drives the LTE Cat 1 Pi HAT. Download [Balena Etcher](https://www.balena.io/etcher/) and follow its instructions to burn the operating system image on to the SD card.

## Assemble the hardware

Pop the Twilio sim card in the HAT and gently attach the antennas.


![A LTE Cat 1 Pi hat. A Twilio SIM card is next to it, but not yet inserted, but with antennas attached.](https://thepracticaldev.s3.amazonaws.com/i/vy8e01ivsr16sivpw9bx.png)

Attach the hat to the Pi with a USB to micro USB cable. The large side goes into the Pi.

![A Raspberry Pi sits on a table. A LTE Cat 1 Pi HAT is attached via the USB-A to micro USD ports. The hat sits next to the pi, but not on top of it, and the HAT has antennas attached.](https://thepracticaldev.s3.amazonaws.com/i/9qza8pgny8n8fqgduylg.png)

Next, put the burned SD card in to the bottom slot on the Pi.

![The bottom of a Raspberry Pi. A SD card is sticking out of it.](https://thepracticaldev.s3.amazonaws.com/i/cyyeo4eooyqg7upp014v.png)

Plug the USB to ethernet adapter into your desktop. Connect the ethernet cable between the ethernet jacks on the adapter and Raspberry Pi.

Finally, plug the Pi in to a USB power source. **Don’t use your laptop**: it doesn’t consistently supply as much power as the Pi needs.

If you see blinking green lights on the Raspberry Pi, you did it right! Next I’ll show you how to set up your development environment.

## Set up your Development Environment

From a terminal on your desktop or laptop, SSH to `pi@192.168.253.100`. You’ll be prompted to enter a password, which is `build19`.

Run the following command to install `pip`, the python package manager:
```sudo apt-get install python3-pip```

Then use pip to install the Twilio Python SDK:
```sudo pip3 install twilio```

[Add Twilio credentials as Environment Variables on the Pi.](https://www.twilio.com/docs/usage/secure-credentials#load-credentials-from-environment-variables)

You need to set `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN`. [You can find them in the console](https://www.twilio.com/console).

Storing your credentials on a device is only acceptable if you plan to keep the device **physically in your possession** at all times. If that’s not the case, use another authentication solution you can disable remotely such as [Trust Onboard](https://www.twilio.com/docs/wireless/trust-onboard) or [API Keys](https://www.twilio.com/docs/iam/pkcv/account-and-key-management-api-keys).

## Configure your text editor

Time to configure your code editor. You have two options to enter the code you’ll need:

- You can use an editor directly on the Pi such as `nano`, `vim`, or `emacs`.
- Alternately, you can use an editor on your laptop and configure an editor extension to copy the code over to the Pi.

When I built my button, I used [atom](https://atom.io/) with the [remote sync extension](https://atom.io/packages/remote-sync) and it worked like a charm.

# Hook up the button

![A Raspberry Pi sits on a table. There is a pink circle around the GPIO pins, to indicate their position on the board.](https://thepracticaldev.s3.amazonaws.com/i/owt2o5hdesi3p7xa0kru.png)

The Raspberry Pi has pins for general purpose input and output, aka **GPIO**.

If you connect the wrong pins you can brick your Pi. I did that during my first build -- guess I'm a real hardware hacker now. 😂 Use a [pinout diagram](https://pinout.xyz/pinout/pin5_gpio3) to double check your pins and avoid my mistake.

Confusingly, the GPIO pins have [several numbering schemes](https://pinout.xyz/). It doesn’t matter which scheme you pick, as long as you use a consistent scheme throughout your project to avoid mixups. For this project we’ll use the BCM numbering scheme.

When the button is pushed, we want to complete a *circuit*.

A circuit is an unbroken path which electric current can flow along. Ground is a reasonably consistent reference point that other levels of current can be measured against.

We measure the voltage difference between the signal and ground to determine if a button is depressed. Circuits can pick up random electromagnetic energy and static, which makes it difficult to set a threshold for exactly how much of a voltage difference matters.

## Resistors: what they are, why you need them

Resistors to the rescue! Resistors impede the flow of electrical current in a circuit. 

For a switch that connects to ground, a *pull-up resistor* ensures a defined voltage (“logical high”) across the remainder of the circuit when the switch is open. Conversely, a *pull-down resistor* ensures a defined ground voltage (“logical low”) when the switch is open.

It doesn’t matter whether you use pull-up or pull-down resistors for this project – so let’s go with pull-up. The Pi GPIO pins have internal pull-up and pull-down resistors, which we’ll configure in our Python code.

## Attach the button to the Pi

Plug the metal side of the button wires into the button. (It doesn’t matter which wire is which, they’re interchangeable.)

Plug the plastic side of the connectors in to [BCM pin 18](https://pinout.xyz/), as well as GND. You can solder these wires instead of using the connectors if you’d prefer.

![a fritzing diagram of a Raspberry Pi and a button plugged in to BCM pin 18 and GND.](https://thepracticaldev.s3.amazonaws.com/i/5kzgcvh4kyvy1qzs3non.png)

# Enter the Code

Copy the following code into a new file `sms_button.py` on your Raspberry Pi. (Use your choice of editor from above).

Replace the `from_number` with your Twilio phone number, and the `to_number` with the number you want to send the affirmations to.

```python
import RPi.GPIO as GPIO
import time
from twilio.rest import Client
import requests

client = Client()

from_number = "" # put your Twilio number here
to_number = "" # put your cell phone number here

# specify which GPIO numbering scheme we are using
GPIO.setmode(GPIO.BCM)
pin_number = 18
# configure the pin for input and set up pull-up resistor
GPIO.setup(pin_number, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def get_affirmation():
    try:
        response = requests.get(url="https://www.affirmations.dev").json()
        return response.get('affirmation')
    except Exception:
        # let's not try too hard
        return "you can do it!"

def send_message(_):
    affirmation = get_affirmation()
    message = client.messages.create(
        body=affirmation,
        from_=from_number,
        to=to_number
    )
    print(message.sid)

GPIO.add_event_detect(
    pin_number,
    GPIO.FALLING,
    callback=send_message,
    bouncetime=1000
)

# we need a loop here to keep the script running continuously
while True:
    time.sleep(10)
```

I’m using an [affirmations api](https://github.com/annthurium/affirmations) here, but you can also write personalized affirmations for yourself. Put the affirmations in a list and use `random.choice()` to select one each time the send_message function is called.

Try running the python script from the command line:

```python3 sms_button.py```

After pushing the button you should see some output that looks like this:

```
sending message
SMef651cc421a241e997c591401dbea41b
```

You should receive a text message affirmation on the cell number you provided. Hooray!

![a GIF of a hand with painted nails pressing a button that's attached to a wooden box with turquoise, teal, and neon yellow stripes.](https://thepracticaldev.s3.amazonaws.com/i/z53c6cbxynoh31vmj8f2.gif)

![a screenshot of text messages received on a mobile device. The messages say "Sucking at something is the first step towards being good at something." "I believe in you." "I know you'll sort it out." "You'll figure it out."](https://thepracticaldev.s3.amazonaws.com/i/fi9mawghb3d58iesfteh.png)

Note that sometimes the button takes a few seconds to initialize when the script first runs.

If you want to keep the script running continuously on the Pi, you’ll want to run it inside a [screen](https://linuxize.com/post/how-to-use-linux-screen/) session so the script can keep going after the ssh session terminates.

# Take that, negative self-talk

At the end of the day, my impostor syndrome doesn’t define me. It’s just a thought I’m having.

Your impostor syndrome doesn’t define you either. You’re smart, you get things done, and I can’t wait to see what you create. If you build something with Twilio IoT, I’d love to hear about it!  You can comment here or find me on [Twitter](https://twitter.com/annthurium).