Table of Contents
Motivation
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 🙂
MicroPython
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.
Buttons
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') sleep(10) print('Going to sleep now') machine.deepsleep()
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
sta_if.active(True)
Now we can connect to our Wi-Fi
sta_if.connect(ssid, password)
You can check the status of the connection via:
sta_if.isconnected():
Writing a Telegram Bot
Create TG bot
- Open Telegram app on your phone
- Search for @botfather
- Start chat
- Send /newbot
- Pick a name
- Pick a username (must be unique)
- 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__': print(bot.get_me()) bot.send_message(chat_id="<your_chat_id>", text="Post ist da")
This program is just used to test the connectivity of your bot.
urequests
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 requests.get("https://api.telegram.org/bot<your_token>/sendMessage?text=hallo&chat_id=<your_chat_id>")
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 = "https://api.telegram.org/bot{}/".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") return if not sta_if.active(): print("MBB: activate network adapter") sta_if.active(True) 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(): pass print("MBB: connected successfully") print(sta_if.ifconfig()) 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) get_url(url) if __name__ == '__main__': print("MBB: start") #disable LED on firebeetle board p2 = machine.Pin(2, machine.Pin.OUT) p2.value(0) 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") sleep(10) print('MBB: Going to sleep now') machine.deepsleep()
Testing
After charging the battery we can use the board independently from the computer
Sources
https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf