Mailbox IoT ESP 32 Project


Out of curiosity I bought a ESP32 board to tinker with, but for almost half a year hadn’t got an idea what to do with it… But then!

Project Idea

The idea: Every time I get mail into my physical snail mail mailbox, the mailbox shall send a message via Telegram to my smartphone:

But with many ideas the execution can become time consuming. Well, let’s see 🙂


As a Python afficionado I was relieved as I found out, that you can use MicroPython on the ESP32 board. I wrote a separate article as a prerequisite:

Using MicroPython on FireBeetle ESP32

From now on I assume, that You have a MicroPython version running on the ESP32.


When the lid of the mailbox is opened, a button shall trigger the action, so we need to configure a GPIO as an input.

This is done via the machine package.

When we don’t want to have external pullups we can enable the internal pullup resistor. Beware: the logic becomes inverted, because the pin is high in idle we pull it down with the button to 0 volts, hence button pressed equals value zero

import machine

button = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP)

while True:
    if not button.value():
        print('Button pressed!')

Deep Sleep

Due to the fact that the device will be battery powered and will just need to send a message once or twice a day, we will need the deepsleep capability.

The machine package gives you access to the deepsleep function as well.

A bit counterintuitive but you also need the esp32 package for defining a wake up cause. One caveat: not every GPIO is able to wake up the ESP32 from deepsleep but GPIO 4 will do it.

import machine 
import esp32 
from time import sleep 

wake1 = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP) 
esp32.wake_on_ext0(pin=wake1, level=esp32.WAKEUP_ALL_LOW) 
print('Im awake. Going to sleep in 10 seconds') 
print('Going to sleep now') 


Setting up Wifi in MicroPython

To be able to send messages we need a WiFi connection. In MicroPython this is handled by the network package.

import network

The ESP32 can either work as a station or as an access point. We need the first option so we use the STA_IF configuration.

sta_if = network.WLAN(network.STA_IF)

the interface has to be activated via

Now we can connect to our Wi-Fi

sta_if.connect(ssid,  password)

You can check the status of the connection via:


Writing a Telegram Bot

Create TG bot

  1. Open Telegram app on your phone
  2. Search for @botfather
  3. Start chat
  4. Send /newbot
  5. Pick a name
  6. Pick a username (must be unique)
  7. Receive credentials

Chat with your bot

Now you can search for your bot’s name and send a message

Python test Program

Telegram has a nice python package which you can pip install

pip install python-telegram-bot --upgrade
import telegram

bot = telegram.Bot(token='<your_token>')

if __name__ == '__main__':
    bot.send_message(chat_id="<your_chat_id>", text="Post ist da")

This program is just used to test the connectivity of your bot.


Because we don’t have access to the telegram package inside the ESP / MicroPython environment we use urequests.

urequests is similar to the requests package and lets you send http messages.

Sending messages looks like the following

import urequests

The complete Code

import network
import urequests
import machine
import esp32
from time import sleep

SSID = <your_ssid>
WIFI_PW = <your_wifi_pw>
TOKEN = <your_tg_token>
URL = "{}/".format(TOKEN)
CHAT_ID = <your_chat_id>

def connect_to_wifi(ssid, password):
    print("MBB: connect_to_wifi")
    sta_if = network.WLAN(network.STA_IF)

    if sta_if.isconnected():
        print("MBB: already connected")

    if not
        print("MBB: activate network adapter")
        print("MBB: network adapter activated")

    if not sta_if.isconnected():
        print("MBB: trying to connect")
        sta_if.connect('%s' % ssid, '%s' % password)

        while not sta_if.isconnected():
        print("MBB: connected successfully")

def get_url(url):
    response = urequests.get(url)
    content = response.text
    return content

def send_message(text, chat_id):
    url = URL + "sendMessage?text={}&chat_id={}".format(text, chat_id)

if __name__ == '__main__':
    print("MBB: start")
    #disable LED on firebeetle board
    p2 = machine.Pin(2, machine.Pin.OUT)
    wake1 = machine.Pin(4, machine.Pin.IN, machine.Pin.PULL_UP) # pin 4 is able to wake
    esp32.wake_on_ext0(pin=wake1, level=esp32.WAKEUP_ALL_LOW)
    print('MBB: Im awake. Going to sleep in 10 seconds')
    connect_to_wifi(SSID, WIFI_PW)
    print("MBB: sending message")
    send_message("Post ist endlich da", CHAT_ID)
    print("MBB: finished")
    print('MBB: Going to sleep now')


After charging the battery we can use the board independently from the computer