Skip to content

Commit 887ea09

Browse files
authored
Initial release (#2)
1 parent 3335f65 commit 887ea09

17 files changed

+1086
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
**/__pycache__/
2+
.DS_Store
3+

README.md

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,99 @@
1-
# Blynk-MicroPython-Edgent
1+
2+
# Blynk.Edgent for MicroPython
3+
4+
Blynk provides custom MicroPython builds specifically designed for IoT applications.
5+
These builds offer a standard MicroPython environment, enriched with numerous fixes, improvements,
6+
and additional features such as **secure Blynk.Cloud connection, device claiming and provisioning, OTA updates, configuration storage**, [and more](#features).
7+
8+
## Getting Started
9+
10+
- Sign up/Log in to your [Blynk Account](https://blynk.cloud)
11+
- Install **Blynk IoT App** for [iOS](https://apps.apple.com/us/app/blynk-iot/id1559317868) or [Android](https://play.google.com/store/apps/details?id=cloud.blynk)
12+
13+
## 1. Install MicroPython + Blynk.Edgent
14+
15+
<details>
16+
<summary>See instructions for <b>ESP32</b> based devices</summary></br>
17+
18+
You can use [**ESP Launchpad**](https://espressif.github.io/esp-launchpad/?flashConfigURL=https://blynk-fw-builds.fra1.cdn.digitaloceanspaces.com/Blynk-Edgent-MicroPython/latest/esp-quickstart.toml) to flash your device. You will need a Chrome-based browser.
19+
20+
1. Plug your board into a USB port
21+
2. Click <kbd>Connect</kbd> in upper right corner and select your board
22+
- Recommended: click <kbd>Erase Flash</kbd> on the **DIY** tab
23+
4. Select **Application** (generic boards vs specialized builds)
24+
5. Select **Develop Kit** variant based on flash size and type
25+
6. Click the <kbd>Flash</kbd> button (if disabled, try clicking the `Connect` button again)
26+
7. Press <kbd>Reset</kbd> button on your board to run the MicroPython firmware
27+
28+
> Alternatively, you can [flash your ESP32 device manually](https://github.com/Blynk-Technologies/Blynk-MicroPython-Edgent/releases/latest)
29+
30+
</details>
31+
32+
<details>
33+
<summary>See instructions for <b>Raspberry Pi Pico W</b></summary></br>
34+
35+
1. Hold down the <kbd>BOOTSEL</kbd> button while plugging the board into a USB port
36+
2. Copy the latest [UF2 firmware file](https://blynk-fw-builds.fra1.cdn.digitaloceanspaces.com/Blynk-Edgent-MicroPython/latest/RPI_PICO_W.uf2) to the USB mass storage device that appears
37+
3. Once programming of the new firmware is complete, the device will automatically reset and be ready for use
38+
39+
</details>
40+
41+
## 2. Connect your device to Blynk.Cloud
42+
43+
1. Open **Blynk IoT App** on your smartphone
44+
2. Click **Add device** -> **Find devices nearby**
45+
3. Select your device and follow the setup instructions
46+
47+
> [!NOTE]
48+
> If you have already created your device in Blynk,
49+
> you can [connect it manually using REPL](_extra/Cookbook.md#manual-device-connection)
50+
51+
## 3. Edit the default MicroPython app
52+
53+
The [`main.py`](./main.py) is a simple `asyncio`-based script that defines the high level device operation.
54+
It could be as simple as this:
55+
56+
```py
57+
from blynk import edgent
58+
from time import ticks_ms
59+
from asyncio import sleep_ms
60+
61+
async def publisher_task():
62+
while True:
63+
await sleep_ms(1000)
64+
edgent.publish("Uptime", ticks_ms())
65+
66+
edgent.run_asyncio_loop([
67+
publisher_task()
68+
])
69+
```
70+
71+
There are many ways to program your device. Here, we'll guide you through the two most popular options:
72+
73+
- [ViperIDE for Web and Mobile](_extra/Workflow-ViperIDE.md)
74+
- [CLI using mpremote](_extra/Workflow-CLI.md)
75+
76+
# Features
77+
78+
- `blynk.inject` - BLE-assisted device claiming and provisioning
79+
- `blynk.air` - OTA updates using **Blynk.Console** and **Blynk.Apps**
80+
- `blynk.time` - Time Zone handling (including DST transitions), Sunrise/Sunset calculation
81+
- `blynk.repl` - Remote MicroPyhton REPL for Blynk Terminal
82+
- `netmgr` - Network management for `WiFi`, `Ethernet` and `Cellular`
83+
- `config` - System-wide configuration
84+
- `aiontp` - A versatile asyncio-based version of NTP client
85+
- `aioinput` - An asyncio variant of `input` function
86+
- `aioprof` - Asyncio [profiling tool](https://gitlab.com/alelec/aioprof)
87+
- `logging` - System-wide, preconfigured logging
88+
- `board` - A unified way to access the board peripherals
89+
- Factory reset function
90+
- Support for TLS certificate bundles
91+
- For `ESP32`:
92+
- `coredump` - Collect crash reports remotely
93+
- OTA updates for MicroPython system firmware
94+
95+
# Further reading
96+
97+
- [Cookbook](_extra/Cookbook.md)
98+
- [`asyncio` documentation](https://docs.micropython.org/en/latest/library/asyncio.html)
99+
- [`asyncio` tutorial](https://github.com/peterhinch/micropython-async/blob/master/v3/docs/TUTORIAL.md)

_extra/Cookbook.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
# MicroPython + Blynk.Edgent Cookbook
3+
4+
## Manual device connection
5+
6+
Connect your device to Blynk.Cloud by directly modifying the device configuration using REPL:
7+
8+
```py
9+
# Add your WiFi network
10+
sysconfig["nets"].append({ "type": "wlan", "ssid": "YourSSID", "psk": "YourPassword" })
11+
12+
# Setup Blynk Template and Auth Token
13+
sysconfig["blynk"].update({
14+
"tmpl_id": "TMPxxxxxxxxxx",
15+
"tmpl_name": "Device",
16+
"auth": "rn60Wxxxxxxxxxxxxxxxxxxxxxxxxxxx",
17+
"server": "blynk.cloud",
18+
})
19+
20+
# Save system configuration
21+
sysconfig.commit()
22+
23+
# Restart
24+
import machine
25+
machine.reset()
26+
```
27+
28+
> [!NOTE]
29+
> When entering the production phase, you can **pre-configure** these settings and enable the **Factory Reset** function. Please contact Blynk for guidance.
30+
31+
## Edit System Config
32+
33+
You can edit `sysconfig` directly from MicroPython REPL:
34+
35+
```py
36+
# Display complete sysconfig
37+
sysconfig
38+
39+
# Display parts of sysconfig
40+
sysconfig.keys()
41+
sysconfig['blynk']
42+
43+
# Enable color logs and set log level
44+
sysconfig["log"].update({ "color": True, "level": "debug" })
45+
46+
# Add your WiFi network
47+
sysconfig["nets"].append({ "type": "wlan", "ssid": "YourSSID", "psk": "YourPassword" })
48+
49+
# Remove network by index (0-based)
50+
del sysconfig["nets"][2]
51+
52+
# Remove all networks
53+
sysconfig['nets'].clear()
54+
55+
# Save system configuration
56+
sysconfig.commit()
57+
```
58+
59+
## Add diagnostics
60+
61+
```py
62+
import netmgr
63+
import micropython
64+
import gc
65+
66+
async def diagnostics_task():
67+
while True:
68+
mem_prev = gc.mem_free()
69+
gc.collect()
70+
mem_free = gc.mem_free()
71+
gc.threshold(mem_free // 4 + gc.mem_alloc())
72+
edgent.publish("ds/Heap Free", mem_free / 1024)
73+
edgent.publish("ds/GC Collect", (mem_free - mem_prev) / 1024)
74+
edgent.publish("ds/WiFi RSSI", netmgr.sta.status("rssi"))
75+
await asyncio.sleep(60)
76+
```
77+
78+
Also, add `diagnostics_task()` to `edgent.run_asyncio_loop`.
79+
80+
## Watchdog Timer (WDT)
81+
82+
The watchdog is typically disabled by default, as it can complicate prototyping.
83+
It is recommended to enable it at later stages of development:
84+
85+
```py
86+
sysconfig["wdt"]["enabled"] = True
87+
sysconfig.commit()
88+
machine.reset() # Changing this setting requires a hard reset
89+
```
90+
91+
## Format internal FS
92+
93+
> [!WARNING]
94+
> This performs a factory reset, the internal file system will recover to it's initial state
95+
96+
```py
97+
from blynk import edgent
98+
edgent.factory_reset()
99+
```
100+
101+
## Update MicroPython firmware directly from GitHub (ESP32 only)
102+
103+
```py
104+
from blynk import air
105+
air.start_ota_update("https://micropython.org/resources/firmware/ESP32_GENERIC-SPIRAM-20240222-v1.22.2.app-bin", validate=False)
106+
```

_extra/Workflow-CLI.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
# Using `mpremote`
3+
4+
Make sure your board is connected via USB. It should **not** be opened by any serial monitor or other tool.
5+
Run these commands on your development machine:
6+
7+
```sh
8+
# Install mpremote utility
9+
pip3 install --upgrade mpremote
10+
11+
# Copy the example files to the device
12+
mpremote cp main.py :
13+
```
14+
15+
> [!NOTE]
16+
> If you have any issues with this, please check out the [`mpremote` documentation](https://docs.micropython.org/en/latest/reference/mpremote.html)
17+
18+
Then, open MicroPython REPL:
19+
20+
```sh
21+
mpremote repl
22+
```
23+
24+
Press `Ctrl+D` to restart your app.
25+
26+
The device should get connected in a few seconds:
27+
28+
```log
29+
___ __ __
30+
/ _ )/ /_ _____ / /__
31+
/ _ / / // / _ \/ '_/
32+
/____/_/\_, /_//_/_/\_\
33+
/___/
34+
35+
Connecting to WiFi_SSID... OK: 192.168.1.123
36+
Connecting to MQTT broker...
37+
Connected to Blynk.Cloud [secure]
38+
```
39+
40+
# Create OTA package
41+
42+
The `cfg/fw.json` will be used to identify the firmware version and type.
43+
Firmware type should match the Blynk Template ID, unless:
44+
- You have a single product that requires differant firmware upgrade packages
45+
- You have multiple products that use a single firmware
46+
47+
```sh
48+
python3 _extra/tools/upy-pack.py -o app_ota.tar.gz main.py cert/ca-bundle.pem `find ./lib -name '*.py'`
49+
```
50+
51+
---
52+
53+
# Further reading
54+
55+
- [Cookbook](Cookbook.md)
56+

_extra/Workflow-ViperIDE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
TODO
3+
4+
---
5+
6+
# Further reading
7+
8+
- [Cookbook](Cookbook.md)
9+

_extra/boards/generic-esp32.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from machine import Pin, RTC
2+
import sys, network
3+
4+
board_id = "Generic ESP32"
5+
6+
class Board:
7+
sta = None
8+
rtc = None
9+
10+
_board = Board()
11+
12+
def rtc():
13+
if _board.rtc is None:
14+
try:
15+
_board.rtc = RTC()
16+
except Exception as e:
17+
sys.print_exception(e)
18+
return _board.rtc
19+
20+
def sta():
21+
if _board.sta is None:
22+
try:
23+
_board.sta = network.WLAN(network.STA_IF)
24+
except Exception as e:
25+
sys.print_exception(e)
26+
return _board.sta

_extra/boards/generic-w600.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from machine import Pin, RTC
2+
import sys, network
3+
4+
board_id = "Generic W600"
5+
6+
class Board:
7+
sta = None
8+
rtc = None
9+
10+
_board = Board()
11+
12+
def rtc():
13+
if _board.rtc is None:
14+
try:
15+
_board.rtc = RTC()
16+
except Exception as e:
17+
sys.print_exception(e)
18+
return _board.rtc
19+
20+
def sta():
21+
if _board.sta is None:
22+
try:
23+
_board.sta = network.WLAN(network.STA_IF)
24+
except Exception as e:
25+
sys.print_exception(e)
26+
return _board.sta

_extra/boards/rpi-pico-w.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from machine import Pin
2+
import sys, network
3+
4+
board_id = "Pi Pico W"
5+
6+
class Board:
7+
sta = None
8+
9+
_board = Board()
10+
11+
def sta():
12+
if _board.sta is None:
13+
try:
14+
_board.sta = network.WLAN(network.STA_IF)
15+
except Exception as e:
16+
sys.print_exception(e)
17+
return _board.sta

0 commit comments

Comments
 (0)