Skip to content

Commit a8e8ca0

Browse files
authored
Merge pull request #324 from DefangLabs/linda-arduino-wifi
Add Arduino Flask Wifi Server sample
2 parents 6d87d1f + 1024611 commit a8e8ca0

File tree

12 files changed

+317
-0
lines changed

12 files changed

+317
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
deploy:
10+
environment: playground
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
id-token: write
15+
16+
steps:
17+
- name: Checkout Repo
18+
uses: actions/checkout@v4
19+
20+
- name: Deploy
21+
uses: DefangLabs/defang-github-action@v1.1.3

samples/arduino-wifi/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Arduino Flask Wifi Server
2+
3+
[![1-click-deploy](https://defang.io/deploy-with-defang.png)](https://portal.defang.dev/redirect?url=https%3A%2F%2Fgithub.com%2Fnew%3Ftemplate_name%3Dsample-<arduino-wifi-template%26template_owner%3DDefangSamples)
4+
5+
![project image](./images/wifi.png)
6+
7+
This sample contains an interactive wifi-connected UI program for a [SenseCAP Indicator Device](https://wiki.seeedstudio.com/Sensor/SenseCAP/SenseCAP_Indicator/Get_started_with_SenseCAP_Indicator/), built for an Embedded Systems project at Defang Software Labs.
8+
9+
The device has a square liquid-crystal touch screen display, and a ESP32-S3 chip that can be programmed in an Arduino environment.
10+
11+
The program `welcome.ino`, acting as a client, pings data every 5 seconds after it is connected to a wifi network. It uses a library called [ArduinoHTTPClient](https://github.com/arduino-libraries/ArduinoHttpClient). It is also recommended to use [Arduino IDE](https://www.arduino.cc/en/software) when coding with `.ino` files. The program UI will display a message that is randomized in color and location on the screen at the same time during pings (every 5 seconds).
12+
13+
The Flask server in `web_server.py` receives these pings when it is initialized and connected to the same wifi network as the client. To initalize it, run `python web_server.py`. To view it, open `localhost` with the port number used. To deploy it to the cloud, run `defang up` in the `\welcome` directory.
14+
15+
A helpful file called `serial_reader.py` decodes serial monitor readings to a readable format, allowing you to see `Serial.println()` messages in real time when running. To initalize it, run `python serial_reader.py` and see it show up in the terminal.
16+
17+
Here is a diagram showing the structure of the application.
18+
19+
![arduino wifi diagram](./images/arduino_wifi_diagram.png)
20+
21+
## Prerequisites
22+
23+
1. Download [Defang CLI](https://github.com/DefangLabs/defang)
24+
2. (Optional) If you are using [Defang BYOC](https://docs.defang.io/docs/concepts/defang-byoc) authenticate with your cloud provider account
25+
3. (Optional for local development) [Docker CLI](https://docs.docker.com/engine/install/)
26+
27+
## Development
28+
29+
To run the application locally, you can use the following command:
30+
31+
```bash
32+
docker compose up --build
33+
```
34+
35+
## Configuration
36+
37+
For this sample, you will not need to provide [configuration](https://docs.defang.io/docs/concepts/configuration).
38+
39+
If you wish to provide configuration, see below for an example of setting a configuration for a value named `API_KEY`.
40+
41+
```bash
42+
defang config set API_KEY
43+
```
44+
45+
## Deployment
46+
47+
> [!NOTE]
48+
> Download [Defang CLI](https://github.com/DefangLabs/defang)
49+
50+
### Defang Playground
51+
52+
Deploy your application to the Defang Playground by opening up your terminal and typing:
53+
```bash
54+
defang compose up
55+
```
56+
57+
### BYOC
58+
59+
If you want to deploy to your own cloud account, you can [use Defang BYOC](https://docs.defang.io/docs/tutorials/deploy-to-your-cloud).
60+
61+
---
62+
63+
Title: Arduino Flask Wifi Server
64+
65+
Short Description: An Arduino wifi server built with Flask.
66+
67+
Tags: Arduino, Flask, Python, IoT, Wifi, Serial
68+
69+
Languages: python
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Use an official Python runtime as a base image
2+
FROM python:3.11-slim
3+
4+
# Set the working directory to /app
5+
WORKDIR /app
6+
7+
# Install required packages
8+
RUN apt-get update -qq \
9+
&& apt-get install -y --no-install-recommends \
10+
build-essential \
11+
python3-dev \
12+
&& apt-get clean \
13+
&& rm -rf /var/lib/apt/lists/*
14+
15+
# Copy the current directory contents into the container at /app
16+
COPY . /app
17+
18+
# Install any needed packages specified in requirements.txt
19+
COPY requirements.txt /app/
20+
RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir -r requirements.txt
21+
22+
# Make port available to the world outside this container
23+
EXPOSE 8081
24+
25+
# Run app.py when the container launches
26+
CMD ["python3", "web_server.py"]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Flask==3.0.0
2+
Werkzeug==3.0.1
3+
Jinja2==3.1.2
4+
itsdangerous==2.1.2
5+
click==8.1.7
6+
blinker==1.7.0
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from flask import Flask, jsonify, request
2+
3+
app = Flask(__name__)
4+
5+
# Sample data
6+
tasks = [
7+
{"id": 1, "title": "Defang x Arduino x Flask example!", "done": False},
8+
{"id": 2, "title": "Pings appear on browser refresh when device is connected.", "done": False}
9+
]
10+
11+
@app.route('/', methods=['GET'])
12+
def home():
13+
return jsonify({"message": "Defang x Arduino x Flask. Go to /tasks to see example!"})
14+
15+
@app.route('/tasks', methods=['GET'])
16+
def get_tasks():
17+
return jsonify({"tasks": tasks})
18+
19+
@app.route('/tasks/<int:task_id>', methods=['GET'])
20+
def get_task(task_id):
21+
task = next((task for task in tasks if task['id'] == task_id), None)
22+
if task:
23+
return jsonify({"task": task})
24+
return jsonify({"error": "Task not found"}), 404
25+
26+
@app.route('/tasks', methods=['POST'])
27+
def create_task():
28+
if not request.json or 'title' not in request.json:
29+
return jsonify({"error": "Bad request"}), 400
30+
task = {
31+
'id': tasks[-1]['id'] + 1,
32+
'title': request.json['title'],
33+
'done': False
34+
}
35+
tasks.append(task)
36+
return jsonify({"task": task}), 201
37+
38+
if __name__ == '__main__':
39+
app.run(debug=True, port=8081, host="0.0.0.0")

samples/arduino-wifi/compose.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
flask:
3+
restart: unless-stopped
4+
build:
5+
context: ./app
6+
dockerfile: Dockerfile
7+
deploy:
8+
resources:
9+
reservations:
10+
cpus: "1.0"
11+
memory: 512M
12+
ports:
13+
- mode: ingress
14+
target: 8081
15+
published: 8081
16+
healthcheck:
17+
test: ["CMD", "python3", "-c", "import sys, urllib.request; urllib.request.urlopen(sys.argv[1]).read()", "http://localhost:8081/"]

samples/arduino-wifi/flash.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
esptool.py --chip esp32s3 --port /dev/tty.usbserial-1110 --baud 921600 write_flash -z 0x0 Default_Factory_Firmware_ESP32-S3_v1.0.0.bin
108 KB
Loading
1.04 MB
Loading

samples/arduino-wifi/merge.bat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
esptool.py --chip esp32s3 \
2+
merge_bin -o sensecap_indicator_basis_v1.0.0.bin \
3+
--flash_mode dio \
4+
--flash_size 8MB \
5+
0x0 ../../build/bootloader/bootloader.bin \
6+
0x8000 ../../build/partition_table/partition-table.bin \
7+
0x10000 ../../build/indicator_basis.bin

0 commit comments

Comments
 (0)