Skip to content

Commit 5e8fd75

Browse files
committed
tutorials/wireless: Add broadcast example.
1 parent 924d383 commit 5e8fd75

File tree

12 files changed

+355
-5
lines changed

12 files changed

+355
-5
lines changed

tutorials/wireless/hub-to-device/drawing.svg

Lines changed: 94 additions & 4 deletions
Loading

tutorials/wireless/hub-to-device/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Communicating with other devices"
2+
title: "Communicating with non-LEGO devices"
33
image:
44
local: "hub-to-device.png"
55
layout: set
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
title: "Hub to hub communication using data broadcasting"
3+
maintainer:
4+
user: "pybricks"
5+
name: "Pybricks and Nard Strijbosch"
6+
image:
7+
local: "../hub-to-hub.png"
8+
description:
9+
"This project shows how you can exchange data between two Pybricks hubs."
10+
video:
11+
youtube: "i--8nBvNn_4"
12+
---
13+
14+
# Experimental features ahead!
15+
16+
Hub to hub communication is still a work in progress. This page explains how
17+
you can install an experimental release on the hub to try it out. This
18+
functionality may change in the future and some things may not work.
19+
20+
# Data broadcasting
21+
22+
When a Bluetooth device is on but not yet connected to anything, it typically
23+
broadcasts (_advertises_) some information about itself. This tells you what
24+
it can do before you connect.
25+
26+
For example, Bluetooth earphones will advertise that they can play music, so
27+
that your phone knows what to look for when it *scans* for speaker devices.
28+
29+
By constantly changing what information the hub advertises, we can broadcast
30+
small amounts of information to nearby devices that are scanning for this
31+
information.
32+
33+
This means that any number of nearby hubs can receive the broadcasted message
34+
without having to set up a connection. This can be quite convenient, but you
35+
can only broadcast small amounts of information at once, as explained below.
36+
37+
**Topics**
38+
39+
All broadcasting data is labeled with a _topic_. This helps you tell data
40+
apart when multiple hubs are broadcasting at the same time. For example, one
41+
hub might be broadcasting tilt sensor data with the topic ``"tilt"`` while
42+
another hub broadcasts measurements with the topic ``"distance"``.
43+
44+
To prepare the hub to send and receive data with these topics, you initialize
45+
the broadcast class as follows:
46+
47+
```python
48+
# Import the experimental Broadcast feature.
49+
from pybricks.experimental import Broadcast
50+
51+
# Prepare the hub for sending and/or receiving these topics.
52+
radio = Broadcast(topics=["tilt", "distance"])
53+
```
54+
55+
**Sending and receiving data tuples**
56+
57+
You can send data as a tuple of values:
58+
59+
```python
60+
# Get some example data as a tuple.
61+
example_data = (123, 456)
62+
63+
# Send it out to anyone listening.
64+
radio.send("tilt", example_data)
65+
```
66+
67+
On another hub, you can receive it as follows:
68+
69+
```python
70+
# Try to read previously received tilt data.
71+
data = radio.receive("tilt")
72+
73+
# Check if there was any data yet:
74+
if data:
75+
# There was, so let's print it.
76+
pitch, roll = data
77+
print(pitch, roll)
78+
79+
```
80+
81+
When sending data tuples like these, your values will be automatically encoded
82+
into a format suitable for broadcasting.
83+
84+
The following data tuples are allowed:
85+
86+
```python
87+
# You can send up to 8 small values in the range +/- 32767.
88+
# Each value counts as 2 bytes.
89+
data = (-1, 2, 3000, 4, 5, 6, -32767, 32767)
90+
91+
# You can send up to 5 big values. Each value counts as 4 bytes.
92+
data = (50000, -50000, 123456, 78910, 43210)
93+
94+
# You can send up to 5 floating point values. Each counts as 4 bytes.
95+
data = (1.234, 3.1428)
96+
97+
# You can send up to 8 strings. Each character counts as 1 byte.
98+
data = ("Hello", "World")
99+
100+
# You can combine up to eight of the above types.
101+
# The total size must be 20 bytes or less.
102+
data = (123, -50000, 3.1428, "Hi!")
103+
104+
```
105+
106+
**Sending and receiving raw data**
107+
108+
If you prefer to encode data yourself, you can send and receive bytes directly:
109+
110+
```python
111+
112+
# Send out up to 23 bytes to anyone listening.
113+
radio.send_bytes("tilt", b"byte data!")
114+
115+
# Read up to 23 bytes.
116+
data = radio.receive_bytes("tilt")
117+
```
118+
119+
# Installing the experimental firmware
120+
121+
To use the broadcasting feature, you have to install a special version of the
122+
Pybricks firmware that includes the ``Broadcast`` class:
123+
124+
1. Download the firmware file for your hub:
125+
- [Technic Hub](./technichub-firmware-build-2178.zip)
126+
- [City Hub](./cityhub-firmware-build-2178.zip)
127+
- [Essential Hub](./essentialhub-firmware-build-2178.zip)
128+
- [Inventor Hub and Prime Hub](./primehub-firmware-build-2178.zip)
129+
2. In [Pybricks Beta](https://beta.pybricks.com/), open the settings menu.
130+
3. Click ``Install Pybricks Firmware``.
131+
4. Instead of selecting your hub, choose ``Advanced`` at the bottom.
132+
5. Follow the instructions to select the firmware file you just downloaded.
133+
6. The installation now proceeds as usual. Make sure to choose a descriptive
134+
hub name. This makes it easy to distinguish them later.
135+
7. Start coding. You can open [Pybricks Beta](https://beta.pybricks.com/) in
136+
multiple different tabs. Use one tab for each hub.
137+
138+
# Running the example programs
139+
140+
The following examples shows the broadcasting feature in action to provide
141+
wireless bidirectional communication.
142+
143+
One hub sends tilt sensor data to control a driving vehicle. The vehicle
144+
sends back a distance measurement to show a warning light for nearby obstacles:
145+
146+
**Run this program on the remote**
147+
148+
You can use any hub with any type of sensor. For example, you could use the
149+
built-in tilt sensor of the Technic Hub, Prime Hub, Essential Hub, or the
150+
Inventor Hub. Alternatively, you could build your own remote control that uses
151+
motors as input dials.
152+
153+
If you don't have the Color Light Matrix, you can delete the lines that
154+
reference it, or adjust it to control the built-in hub light.
155+
156+
{% include copy-code.html %}
157+
```python
158+
{% include_relative remote.py %}
159+
```
160+
161+
**Run this program on the vehicle**
162+
163+
You can use any hub with any type of motors. If you don't have a distance
164+
sensor, you can delete the lines that make use of the Ultrasonic Sensor.
165+
166+
{% include copy-code.html %}
167+
```python
168+
{% include_relative vehicle.py %}
169+
```
170+
171+
# Known issues: Slow communication while connected to computer
172+
173+
If the hub is still connected to the computer, the bluetooth chip is quite busy
174+
and data broadcasting may be slow. Especially on the Technic Hub and the City
175+
Hub.
176+
177+
This is something we are still working on. To work around it, just load the
178+
program onto the hub and disconnect from your computer. You can just restart
179+
the program with the hub button.
180+
Binary file not shown.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from pybricks.pupdevices import TiltSensor, ColorLightMatrix
2+
from pybricks.parameters import Port, Color
3+
from pybricks.tools import wait
4+
from pybricks.experimental import Broadcast
5+
6+
# Initialize the devices.
7+
lights = ColorLightMatrix(Port.A)
8+
sensor = TiltSensor(Port.B)
9+
10+
# Initialize broadcast with two topics.
11+
radio = Broadcast(topics=["tilt", "distance"])
12+
13+
while True:
14+
# Read pitch and roll.
15+
pitch, roll = sensor.tilt()
16+
17+
# Make small tilt zero.
18+
if abs(pitch) < 5:
19+
pitch = 0
20+
if abs(roll) < 5:
21+
roll = 0
22+
23+
# Send the data!
24+
radio.send("tilt", (pitch, roll))
25+
26+
# Check for distance data.
27+
data = radio.receive("distance")
28+
29+
# If there was distance data, use it to activate the light.
30+
if data and data < 500:
31+
lights.on(Color.RED)
32+
else:
33+
lights.off()
34+
35+
# Wait some time.
36+
wait(10)
Binary file not shown.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from pybricks.pupdevices import Motor, UltrasonicSensor
2+
from pybricks.parameters import Port, Direction
3+
from pybricks.robotics import DriveBase
4+
from pybricks.tools import wait
5+
from pybricks.experimental import Broadcast
6+
7+
# Initialize broadcast with two topics.
8+
radio = Broadcast(topics=["tilt", "distance"])
9+
10+
# Initialize the drive base.
11+
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
12+
right_motor = Motor(Port.B)
13+
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=112)
14+
15+
# Initialize the distance sensor.
16+
sensor = UltrasonicSensor(Port.C)
17+
18+
while True:
19+
20+
# Receive tilt data
21+
data = radio.receive("tilt")
22+
23+
# If we received it, start driving.
24+
if data:
25+
pitch, roll = data
26+
drive_base.drive(speed=pitch * 8, turn_rate=roll * 3)
27+
else:
28+
print(data)
29+
drive_base.stop()
30+
31+
32+
# Send the distance data
33+
radio.send("distance", sensor.distance())
34+
35+
# Wait some time.
36+
wait(50)

0 commit comments

Comments
 (0)