examples: import snippets from pybricks-projects

These code samples are rendered in the docs, so we include them here.

For the git history of these snippets, see:
https://github.com/pybricks/pybricks-projects/commits/f4914069aaacfd9ab1e0dd6f05524f62cfc56b29/snippets
This commit is contained in:
Laurens Valk
2020-11-04 10:17:33 +01:00
committed by laurensvalk
parent 30e87695ea
commit b0ffb24a2e
181 changed files with 3719 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/client.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env pybricks-micropython
# Before running this program, make sure the client and server EV3 bricks are
# paired using Bluetooth, but do NOT connect them. The program will take care
# of establishing the connection.
# The server must be started before the client!
from pybricks.messaging import BluetoothMailboxClient, TextMailbox
# This is the name of the remote EV3 or PC we are connecting to.
SERVER = 'ev3dev'
client = BluetoothMailboxClient()
mbox = TextMailbox('greeting', client)
print('establishing connection...')
client.connect(SERVER)
print('connected!')
# In this program, the client sends the first message and then waits for the
# server to reply.
mbox.send('hello!')
mbox.wait()
print(mbox.read())
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "PC Bluetooth Example",
"type": "python",
"request": "launch",
"program": "pcclient.py",
"console": "integratedTerminal"
}
]
}
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
from pybricks.messaging import BluetoothMailboxClient, TextMailbox
# This demo makes your PC talk to an EV3 over Bluetooth.
#
# This is identical to the EV3 client example in ../bluetooth_client
#
# The only difference is that it runs in Python3 on your computer, thanks to
# the Python3 implementation of the messaging module that is included here.
# As far as the EV3 is concerned, it thinks it just talks to an EV3 client.
#
# So, the EV3 server example needs no further modifications. The connection
# procedure is also the same as documented in the messaging module docs:
# https://docs.pybricks.com/en/latest/messaging.html
#
# So, turn Bluetooth on on your PC and the EV3. You may need to make Bluetooth
# visible on the EV3. You can skip pairing if you already know the EV3 address.
# This is the address of the server EV3 we are connecting to.
SERVER = 'CC:78:AB:D8:4E:F6'
client = BluetoothMailboxClient()
mbox = TextMailbox('greeting', client)
print('establishing connection...')
client.connect(SERVER)
print('connected!')
# In this program, the client sends the first message and then waits for the
# server to reply.
mbox.send('hello!')
mbox.wait()
print(mbox.read())
@@ -0,0 +1,9 @@
This is a partial implementation of the pybricks package that is normally
included in Pybricks MicroPython for EV3. It makes the PC look like an EV3 so
other EV3 bricks can connect to it and vice versa.
It has the same end user API, so the same documentation applies:
https://docs.pybricks.com/en/latest/messaging.html
This is a Python3 modification of the original Pybricks MicroPython version:
https://github.com/pybricks/pybricks-micropython/tree/master/bricks/ev3dev
@@ -0,0 +1,145 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2020 The Pybricks Authors
"""
:class:`RFCOMMServer` can be used to communicate with other Bluetooth RFCOMM
devices that don't support the EV3 mailbox protocol.
It is based on the standard library ``socketserver`` module and attempts to
remain a strict subset of that implementation when it comes to low-level
implementation details.
"""
from bluetooth import BluetoothSocket, RFCOMM
from socketserver import ThreadingMixIn
BDADDR_ANY = ""
def str2ba(string, ba):
"""Convert string to Bluetooth address"""
for i, v in enumerate(string.split(':')):
ba.b[5-i] = int(v, 16)
def ba2str(ba):
"""Convert Bluetooth address to string"""
string = []
for b in ba.b:
string.append('{:02X}'.format(b))
string.reverse()
return ':'.join(string).upper()
class RFCOMMServer:
"""Object that simplifies setting up an RFCOMM socket server.
This is based on the ``socketserver.SocketServer`` class in the Python
standard library.
"""
request_queue_size = 1
def __init__(self, server_address, RequestHandlerClass):
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.socket = BluetoothSocket(RFCOMM)
try:
self.socket.bind((server_address[0], server_address[1]))
# self.server_address = self.socket.getsockname()
self.socket.listen(self.request_queue_size)
except Exception:
self.server_close()
raise
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.server_close()
def handle_request(self):
try:
request, addr_data = self.socket.accept()
except OSError:
return
try:
self.process_request(request, addr_data)
except Exception:
request.close()
raise
def process_request(self, request, client_address):
self.finish_request(request, client_address)
request.close()
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)
def server_close(self):
self.socket.close()
class StreamRequestHandler:
"""Class that handles incoming requests.
This is based on ``socketserver.StreamRequestHandler`` from the Python
standard library.
"""
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()
def setup(self):
self.wfile = self.request
self.rfile = self.request
def handle(self):
pass
def finish(self):
pass
class ThreadingRFCOMMServer(ThreadingMixIn, RFCOMMServer):
"""Version of :class:`RFCOMMServer` that handles connections in a new
thread.
"""
pass
class RFCOMMClient:
def __init__(self, client_address, RequestHandlerClass):
self.client_address = client_address
self.RequestHandlerClass = RequestHandlerClass
self.socket = BluetoothSocket(RFCOMM)
def handle_request(self):
self.socket.connect((self.client_address[0], self.client_address[1]))
try:
self.process_request(self.socket, self.client_address)
except Exception:
self.socket.close()
raise
def process_request(self, request, client_address):
self.finish_request(request, client_address)
request.close()
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)
def client_close(self):
self.socket.close()
class ThreadingRFCOMMClient(ThreadingMixIn, RFCOMMClient):
pass
@@ -0,0 +1,340 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2020 The Pybricks Authors
from _thread import allocate_lock
from errno import ECONNRESET
from struct import pack, unpack
from .bluetooth import (BDADDR_ANY, ThreadingRFCOMMServer,
ThreadingRFCOMMClient, StreamRequestHandler)
def resolve(brick):
"""Fake resolver to get address from Bluetooth name.
To connect to an EV3 server, you must specify its full address.
"""
return brick
class Mailbox:
def __init__(self, name, connection, encode=None, decode=None):
"""Object that represents a mailbox for sending an receiving messages
from other connected devices.
Arguments:
name (str):
The name of this mailbox.
connection:
A connection object that implements the mailbox connection
interface.
encode:
A function that encodes an object into a bytes-like object.
decode:
A function that decodes an object from a bytes-like object.
"""
self.name = name
self._connection = connection
if encode:
self.encode = encode
if decode:
self.decode = decode
def encode(self, value):
return value
def decode(self, payload):
return payload
def read(self):
"""Reads the current value of the mailbox.
Returns:
The decoded value or ``None`` if the mailbox has never received
a value.
"""
data = self._connection.read_from_mailbox(self.name)
if data is None:
return None
return self.decode(data)
def send(self, value, destination=None):
"""Sends a value to remote mailboxes with the same name as this
mailbox.
Arguments:
value: The value to send.
destination: The name or address of a specific device or ``None``
to broadcast to all connected devices.
"""
data = self.encode(value)
self._connection.send_to_mailbox(destination, self.name, data)
def wait(self):
"""Waits for the mailbox to receive a message."""
self._connection.wait_for_mailbox_update(self.name)
def wait_new(self):
"""Waits for the mailbox to receive a message that is different from
the current contents of the mailbox.
Returns:
The new value. (Same as return value of :meth:`read`.)
"""
old = self.read()
while True:
self.wait()
new = self.read()
if new != old:
return new
class LogicMailbox(Mailbox):
""":class:`Mailbox` that holds a logic or boolean value.
This is compatible with the "logic" message blocks in the standard
EV3 firmware.
"""
def encode(self, value):
return b'\x01' if value else b'\x00'
def decode(self, payload):
return bool(payload[0])
class NumericMailbox(Mailbox):
""":class:`Mailbox` that holds a numeric or floating point value.
This is compatible with the "numeric" message blocks in the standard
EV3 firmware.
"""
def encode(self, value):
return pack('<f', value)
def decode(self, payload):
return unpack('<f', payload)[0]
class TextMailbox(Mailbox):
""":class:`Text` that holds a text or string point value.
This is compatible with the "text" message blocks in the standard
EV3 firmware.
"""
def encode(self, value):
return ('{}\0'.format(value)).encode('utf-8')
def decode(self, payload):
return payload.decode().strip('\0')
# EV3 standard firmware is hard-coded to use channel 1
EV3_RFCOMM_CHANNEL = 1
# EV3 VM bytecodes
SYSTEM_COMMAND_NO_REPLY = 0x81
WRITEMAILBOX = 0x9E
class MailboxHandler(StreamRequestHandler):
def handle(self):
with self.server._lock:
self.server._clients[self.client_address[0]] = self.request
while True:
try:
buf = self.rfile.recv(2)
if len(buf) == 0:
break
except OSError as ex:
# The client disconnected the connection
if ex.args[0] == ECONNRESET:
break
raise
size, = unpack('<H', buf)
buf = self.rfile.recv(size)
msg_count, cmd_type, cmd, name_size = unpack('<HBBB', buf[0:5])
if cmd_type != SYSTEM_COMMAND_NO_REPLY:
raise ValueError('Bad message type')
if cmd != WRITEMAILBOX:
raise ValueError('Bad command')
mbox = buf[5:5+name_size].decode().strip('\0')
data_size, = unpack('<H', buf[5+name_size:7+name_size])
data = buf[7+name_size:7+name_size+data_size]
with self.server._lock:
self.server._mailboxes[mbox] = data
update_lock = self.server._updates.get(mbox)
if update_lock:
update_lock.release()
class MailboxHandlerMixIn:
def __init__(self):
# protects against concurrent access of other attributes
self._lock = allocate_lock()
# map of mailbox name to raw data
self._mailboxes = {}
# map of device name/address to object with send() method
self._clients = {}
# map of mailbox name to mutex lock
self._updates = {}
# map of names to addresses
self._addresses = {}
def read_from_mailbox(self, mbox):
"""Reads the current raw data from a mailbox.
Arguments:
mbox (str):
The name of the mailbox.
Returns:
bytes:
The current mailbox raw data or ``None`` if nothing has ever
been delivered to the mailbox.
"""
with self._lock:
return self._mailboxes.get(mbox)
def send_to_mailbox(self, brick, mbox, payload):
"""Sends a mailbox value using raw bytes data.
Arguments:
brick (str):
The name or address of the brick or ``None``` to broadcast to
all connected devices
mbox (str):
The name of the mailbox.
payload (bytes):
A bytes-like object that will be sent to the mailbox.
"""
mbox_len = len(mbox) + 1
payload_len = len(payload)
send_len = 7 + mbox_len + payload_len
fmt = '<HHBBB{}sH{}s'.format(mbox_len, payload_len)
data = pack(fmt, send_len, 1, SYSTEM_COMMAND_NO_REPLY, WRITEMAILBOX,
mbox_len, mbox.encode('utf-8'), payload_len, payload)
with self._lock:
if brick is None:
for client in self._clients.values():
client.send(data)
else:
addr = self._addresses.get(brick)
if addr is None:
addr = resolve(brick)
self._addresses[brick] = addr
if addr is None:
raise ValueError('no paired devices matching "{}"'.format(brick))
self._clients[addr].send(data)
def wait_for_mailbox_update(self, mbox):
"""Waits until ``mbox`` receives a value."""
lock = allocate_lock()
lock.acquire()
with self._lock:
self._updates[mbox] = lock
try:
return lock.acquire()
finally:
with self._lock:
del self._updates[mbox]
class BluetoothMailboxServer(MailboxHandlerMixIn, ThreadingRFCOMMServer):
def __init__(self):
"""Object that represents an incoming Bluetooth connection from another
EV3.
The remote EV3 can either be running MicroPython or the standard EV3
firmare.
"""
super().__init__()
super(ThreadingRFCOMMServer, self).__init__(
(BDADDR_ANY, EV3_RFCOMM_CHANNEL), MailboxHandler)
def wait_for_connection(self, count=1):
"""Waits for a :class:`BluetoothMailboxClient` on a remote device to
connect.
Arguments:
count (int):
The number of remote connections to wait for.
Raises:
OSError:
There was a problem establishing the connection.
"""
for _ in range(count):
self.handle_request()
class MailboxRFCOMMClient(ThreadingRFCOMMClient):
def __init__(self, parent, bdaddr):
self.parent = parent
super().__init__((bdaddr, EV3_RFCOMM_CHANNEL), MailboxHandler)
def send(self, data):
self.socket.send(data)
def shutdown_request(self, request):
request.close()
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self.parent)
class BluetoothMailboxClient(MailboxHandlerMixIn):
"""Object that represents outgoing Bluetooth connections to one or more
remote EV3s.
The remote EV3s can either be running MicroPython or the standard EV3
firmare.
"""
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
def connect(self, brick):
"""Connects to a :class:`BluetoothMailboxServer` on another device.
The remote device must be paired and waiting for a connection. See
:meth:`BluetoothMailboxServer.wait_for_connection`.
Arguments:
brick (str):
The name or address of the remote EV3 to connect to.
Raises:
TypeError:
``brick`` is not a string
ValueError:
There are no paired Bluetooth devices that match ``brick``
or connection to ``brick`` already exists.
OSError:
There was a problem establishing the connection.
"""
addr = resolve(brick)
if addr is None:
raise ValueError('no paired devices matching "{}"'.format(brick))
client = MailboxRFCOMMClient(self, addr)
if self._clients.setdefault(addr, client) is not client:
raise ValueError('connection with this address already exists')
try:
client.handle_request()
except Exception:
del self._clients[addr]
raise
def close(self):
"""Closes the connections."""
for client in self._clients.values():
client.client_close()
self._clients.clear()
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
@@ -0,0 +1,8 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"python.languageServer": "None",
"ev3devBrowser.download.exclude": "{**/.*,**/*.md}"
}
@@ -0,0 +1,6 @@
To find the SPIKE Prime Bluetooth address:
- Press the Bluetooth button on SPIKE to make it discoverable.
- Use the menu on the EV3 screen and go to:
Wireless and Networks > Bluetooth > Start Scan.
- Scroll down the list and choose your SPIKE hub.
- No need to pair or connect! Just write down the address you see.
@@ -0,0 +1,80 @@
from uctypes import addressof, sizeof, struct
from usocket import socket, SOCK_STREAM
from _thread import start_new_thread
from pybricks.bluetooth import (
str2ba,
sockaddr_rc,
AF_BLUETOOTH,
BTPROTO_RFCOMM
)
from pybricks.tools import wait, StopWatch
def get_bluetooth_rfcomm_socket(address, channel):
addr_data = bytearray(sizeof(sockaddr_rc))
addr = struct(addressof(addr_data), sockaddr_rc)
addr.rc_family = AF_BLUETOOTH
str2ba(address, addr.rc_bdaddr)
addr.rc_channel = channel
sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
sock.connect(addr_data)
return sock
class SpikePrimeStreamReader():
def __init__(self, address):
try:
self.sock = get_bluetooth_rfcomm_socket(address, 1)
except OSError as e:
print("Turn on Bluetooth on the EV3 and on SPIKE.")
raise e
self._values = None
start_new_thread(self.reader, ())
watch = StopWatch()
while watch.time() < 2000:
if self.values() is not None:
return
wait(100)
raise IOError("No data received")
def disconnect(self):
self.sock.close()
def reader(self):
while True:
try:
raw = self.sock.recv(1024)
except OSError:
break
try:
data = eval(raw)
if data['m'] == 0:
self._values = data['p']
except (SyntaxError, KeyError):
pass
def values(self):
return self._values
def device(self, port):
if 'A' <= port <= 'F':
return self.values()[ord(port)-ord('A')][1]
else:
raise ValueError
def acceleration(self):
return self.values()[6]
def gyro(self):
return self.values()[7]
def orientation(self):
return self.values()[8]
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
from connection import SpikePrimeStreamReader
# Beep!
ev3 = EV3Brick()
ev3.speaker.beep()
# Create the connection. See README.md to find the address for your SPIKE hub.
spike = SpikePrimeStreamReader('F4:84:4C:AA:C8:A4')
# Now you can simply read values!
for i in range(100):
print(spike.values())
wait(100)
@@ -0,0 +1,28 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
from pybricks.ev3devices import Motor
from pybricks.robotics import DriveBase
from pybricks.parameters import Port
from connection import SpikePrimeStreamReader
# Beep!
ev3 = EV3Brick()
ev3.speaker.beep()
# Create the connection. See README.md to find the address for your SPIKE hub.
spike = SpikePrimeStreamReader('F4:84:4C:AA:C8:A4')
# Initialize the motors and drive base
left_motor = Motor(Port.B)
right_motor = Motor(Port.C)
robot = DriveBase(left_motor, right_motor, wheel_diameter=55.5, axle_track=104)
while True:
# Read the orientation
yaw, pitch, roll = spike.orientation()
# Set speed and turn rate based on orientation
robot.drive(-pitch*6, roll*2)
wait(20)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/server.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env pybricks-micropython
# Before running this program, make sure the client and server EV3 bricks are
# paired using Bluetooth, but do NOT connect them. The program will take care
# of establishing the connection.
# The server must be started before the client!
from pybricks.messaging import BluetoothMailboxServer, TextMailbox
server = BluetoothMailboxServer()
mbox = TextMailbox('greeting', server)
# The server must be started before the client!
print('waiting for connection...')
server.wait_for_connection()
print('connected!')
# In this program, the server waits for the client to send the first message
# and then sends a reply.
mbox.wait()
print(mbox.read())
mbox.send('hello to you!')
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
from pybricks.parameters import Button
# Initialize the EV3
ev3 = EV3Brick()
# Wait until any of the buttons are pressed
while not any(ev3.buttons.pressed()):
wait(10)
# Do something if the left button is pressed
if Button.LEFT in ev3.buttons.pressed():
print("The left button is pressed.")
# Wait until all buttons are released
while any(ev3.buttons.pressed()):
wait(10)
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+7
View File
@@ -0,0 +1,7 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"ev3devBrowser.download.exclude": "{**/.*,**/*.svg}"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

+101
View File
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="178"
height="128"
viewBox="0 0 47.095832 33.866668"
version="1.1"
id="svg8"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="buttons.svg"
inkscape:export-filename="buttons.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="95.61633"
inkscape:cy="59.069332"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1172"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-263.13332)">
<g
id="g902"
transform="matrix(0.95808471,0,0,0.95808471,2.2603677,8.2065667)">
<path
sodipodi:nodetypes="ccccccccccccccc"
inkscape:connector-curvature="0"
id="path826"
d="m 16.426577,278.66756 v -3.65654 l -2.03331,-2.0333 5.407037,-5.45361 h 6.57702 l 5.276386,5.27638 -1.936759,1.93676 v 3.93031 H 27.55869 v -2.63536 c -0.02145,-0.56645 -0.457827,-1.225 -1.215443,-1.21545 l -6.472149,0.0466 c -0.859483,0.0241 -1.289242,0.61856 -1.289277,1.28929 v 2.53879 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.09010255;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="0.48594931"
rx="0.48594931"
y="276.09946"
x="19.694563"
height="6.7310009"
width="6.7310009"
id="rect830"
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.09010255;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path832"
d="m 36.519182,276.14245 a 3.1807595,3.1807595 0 0 0 -0.225076,0.008 h -5.220895 v 6.34453 h 5.265875 a 3.1807595,3.1807595 0 0 0 0.180096,0.009 3.1807595,3.1807595 0 0 0 3.180785,-3.18078 3.1807595,3.1807595 0 0 0 -3.180785,-3.18061 z"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.09010255;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.09010255;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 9.6389609,276.14245 a 3.1807595,3.1807595 0 0 1 0.2250761,0.008 h 5.220895 v 6.34453 H 9.8190572 a 3.1807595,3.1807595 0 0 1 -0.1800963,0.009 3.1807595,3.1807595 0 0 1 -3.1807864,-3.18078 3.1807595,3.1807595 0 0 1 3.1807864,-3.18061 z"
id="path841" />
<path
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.09010255;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 16.426577,280.20003 v 3.65654 l -2.03331,2.0333 5.407037,5.45361 h 6.57702 l 5.276386,-5.27638 -1.936759,-1.93676 v -3.93031 H 27.55869 v 2.63536 c -0.02145,0.56645 -0.457827,1.225 -1.215443,1.21545 l -6.472149,-0.0466 c -0.859483,-0.0241 -1.289242,-0.61856 -1.289277,-1.28929 v -2.53879 z"
id="path822"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccc" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2.2049736,289.18236 H 44.567193"
id="path818"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.parameters import Button
from menu import wait_for_button
# Initialize the EV3.
ev3 = EV3Brick()
while True:
# Show the menu and wait for one button to be selected.
button = wait_for_button(ev3)
# Now you can do something, based on which button was pressed.
# In this demo, we just play a different sound for each button.
if button == Button.LEFT:
ev3.speaker.beep(200)
elif button == Button.RIGHT:
ev3.speaker.beep(400)
elif button == Button.UP:
ev3.speaker.beep(600)
elif button == Button.DOWN:
ev3.speaker.beep(800)
elif button == Button.CENTER:
ev3.speaker.beep(1000)
+30
View File
@@ -0,0 +1,30 @@
def wait_for_button(ev3):
"""
This function shows a picture of the buttons on the EV3 screen.
Then it waits until you press a button.
It returns which button was pressed.
"""
# Show a picture of the buttons on the screen.
ev3.screen.load_image('buttons.png')
# Tip: add text or icons to the image to help you
# remember what each button will do in your program.
# Wait for a single button to be pressed and save the result.
pressed = []
while len(pressed) != 1:
pressed = ev3.buttons.pressed()
button = pressed[0]
# Print which button was pressed
ev3.screen.draw_text(2, 100, button)
# Now wait for the button to be released.
while any(ev3.buttons.pressed()):
pass
# Return which button was pressed.
return button
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
+7
View File
@@ -0,0 +1,7 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"python.languageServer": "None"
}
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env pybricks-micropython
from pybricks.ev3devices import Motor
from pybricks.parameters import Port
from pybricks.tools import DataLog, StopWatch, wait
# Create a data log file in the project folder on the EV3 Brick.
# * By default, the file name contains the current date and time, for example:
# log_2020_02_13_10_07_44_431260.csv
# * You can optionally specify the titles of your data columns. For example,
# if you want to record the motor angles at a given time, you could do:
data = DataLog('time', 'angle')
# Initialize a motor and make it move
wheel = Motor(Port.B)
wheel.run(500)
# Start a stopwatch to measure elapsed time
watch = StopWatch()
# Log the time and the motor angle 10 times
for i in range(10):
# Read angle and time
angle = wheel.angle()
time = watch.time()
# Each time you use the log() method, a new line with data is added to
# the file. You can add as many values as you like.
# In this example, we save the current time and motor angle:
data.log(time, angle)
# Wait some time so the motor can move a bit
wait(100)
# You can now upload your file to your computer
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
+7
View File
@@ -0,0 +1,7 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"python.languageServer": "None"
}
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env pybricks-micropython
from pybricks.parameters import Color
from pybricks.tools import DataLog
# Create a data log file called my_file.txt
data = DataLog('time', 'angle', name='my_file', timestamp=False, extension='txt')
# The log method uses the print() method to add a line of text.
# So, you can do much more than saving numbers. For example:
data.log('Temperature', 25)
data.log('Sunday', 'Monday', 'Tuesday')
data.log({'Kiwi': Color.GREEN}, {'Banana': Color.YELLOW})
# You can upload the file to your computer, but you can also print the data:
print(data)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+20
View File
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Main Example",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
},
{
"name": "Class Example",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/class_example.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
@@ -0,0 +1,46 @@
#!/usr/bin/env pybricks-micropython
from pybricks.parameters import Port
from pybricks.iodevices import Ev3devSensor
class MySensor(Ev3devSensor):
"""Example of extending the Ev3devSensor class."""
def __init__(self, port):
"""Initialize the sensor."""
# Initialize the parent class.
super().__init__(port)
# Get the sysfs path.
self.path = '/sys/class/lego-sensor/sensor' + str(self.sensor_index)
def get_modes(self):
"""Get a list of mode strings so we don't have to look them up."""
# The path of the modes file.
modes_path = self.path + '/modes'
# Open the modes file.
with open(modes_path, 'r') as m:
# Read the contents.
contents = m.read()
# Strip the newline symbol, and split at every space symbol.
return contents.strip().split(' ')
# Initialize the sensor
sensor = MySensor(Port.S3)
# Show where this sensor can be found
print(sensor.path)
# Print the available modes
modes = sensor.get_modes()
print(modes)
# Read mode 0 of this sensor
val = sensor.read(modes[0])
print(val)
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env pybricks-micropython
from pybricks.parameters import Port
from pybricks.tools import wait
from pybricks.iodevices import Ev3devSensor
# Initialize an Ev3devSensor.
# In this example we use the
# LEGO MINDSTORMS EV3 Color Sensor.
sensor = Ev3devSensor(Port.S3)
while True:
# Read the raw RGB values
r, g, b = sensor.read('RGB-RAW')
# Print results
print('R: {0}\t G: {1}\t B: {2}'.format(r, g, b))
# Wait
wait(200)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor
from pybricks.parameters import Port
# Create your objects here
# Initialize the EV3 Brick.
ev3 = EV3Brick()
# Initialize a motor at port B.
test_motor = Motor(Port.B)
# Write your program here
# Play a sound.
ev3.speaker.beep()
# Run the motor up to 500 degrees per second. To a target angle of 90 degrees.
test_motor.run_target(500, 90)
# Play another beep sound.
ev3.speaker.beep(frequency=1000, duration=500)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.iodevices import I2CDevice
from pybricks.parameters import Port
# Initialize the EV3
ev3 = EV3Brick()
# Initialize I2C Sensor
device = I2CDevice(Port.S2, 0xD2 >> 1)
# Read one byte from the device.
# For this device, we can read the Who Am I
# register (0x0F) for the expected value: 211.
if 211 not in device.read(0x0F):
raise OSError("Device is not attached")
# To write data, create a bytes object of one
# or more bytes. For example:
# data = bytes((1, 2, 3))
# Write one byte (value 0x08) to register 0x22
device.write(0x22, bytes((0x08,)))
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.iodevices import I2CDevice
from pybricks.parameters import Port
# Initialize the EV3
ev3 = EV3Brick()
# Initialize I2C Sensor
device = I2CDevice(Port.S2, 0xD2 >> 1)
# Recommended for reading
result, = device.read(reg=0x0F, length=1)
# Read 1 byte from no particular register:
device.read(reg=None, length=1)
# Read 0 bytes from no particular register:
device.read(reg=None, length=0)
# I2C write operations consist of a register byte followed
# by a series of data bytes. Depending on your device, you
# can choose to skip the register or data as follows:
# Recommended for writing:
device.write(reg=0x22, data=b'\x08')
# Write 1 byte to no particular register:
device.write(reg=None, data=b'\x08')
# Write 0 bytes to a particular register:
device.write(reg=0x08, data=None)
# Write 0 bytes to no particular register:
device.write(reg=None, data=None)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
from pybricks.parameters import Color
# Initialize the EV3
ev3 = EV3Brick()
# Turn on a red light
ev3.light.on(Color.RED)
# Wait
wait(1000)
# Turn the light off
ev3.light.off()
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
+7
View File
@@ -0,0 +1,7 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"python.languageServer": "None"
}
+145
View File
@@ -0,0 +1,145 @@
#!/usr/bin/env pybricks-micropython
from pybricks.ev3devices import Motor
from pybricks.parameters import Port
import struct
# This program uses the two PS4 sticks to control two EV3 Large Servo Motors
# using tank like controls. For a full map of all PS4 buttons, trackpad, and
# motion checkout: https://github.com/codeadamca/python-connect-ps4
# Initialize EV3 motors
left_motor = Motor(Port.B)
right_motor = Motor(Port.C)
left_speed = 0
right_speed = 0
# Locate the event file you want to react to, on my setup the PS4 controller
# button events are located in /dev/input/event4
infile_path = "/dev/input/event4"
in_file = open(infile_path, "rb")
# Define the format the event data will be read.
# https://docs.python.org/3/library/struct.html#format-characters
FORMAT = 'llHHi'
EVENT_SIZE = struct.calcsize(FORMAT)
event = in_file.read(EVENT_SIZE)
# A helper function for converting stick values (0 to 255) to more usable
# numbers (-100 to 100)
def scale(val, src, dst):
result = (float(val - src[0]) / (src[1] - src[0]))
result = result * (dst[1] - dst[0]) + dst[0]
return result
# Create a loop to react to events
# This loop reacte to all main PS4 button and stick events. I have left out
# buttons like share and options, but can easily be added in by referring
# to the table at: https://github.com/codeadamca/python-connect-ps4
while event:
# Place event data into variables
(tv_sec, tv_usec, ev_type, code, value) = struct.unpack(FORMAT, event)
# If a button was pressed or released
if ev_type == 1:
# React to the X button
if code == 304 and value == 0:
print("The X button was released")
elif code == 304 and value == 1:
print("The X button was pressed")
# React to the Circle button
elif code == 305 and value == 0:
print("The Circle button was released")
elif code == 305 and value == 1:
print("The Circle button was pressed")
# React to the Triangle button
elif code == 307 and value == 0:
print("The Triangle button was released")
elif code == 307 and value == 1:
print("The Triangle button was pressed")
# React to the Square button
elif code == 308 and value == 0:
print("The Square button was released")
elif code == 308 and value == 1:
print("The Square button was pressed")
# React to the L1 button
elif code == 310 and value == 0:
print("The L1 button was released")
elif code == 310 and value == 1:
print("The L1 button was pressed")
# React to the R1 button
elif code == 311 and value == 0:
print("The R1 button was released")
elif code == 311 and value == 1:
print("The R1 button was pressed")
# React to the L2 button
elif code == 312 and value == 0:
print("The L2 button was released")
elif code == 312 and value == 1:
print("The L2 button was pressed")
# React to the R2 button
elif code == 313 and value == 0:
print("The R2 button was released")
elif code == 313 and value == 1:
print("The R2 button was pressed")
elif ev_type == 3:
# The sticks often trigger non-stop events, comment this out if you are
# not using the sticks as part of your project, or it becomes hard to
# read other data
# React to the left stick vertical
if code == 1:
print("The left stick vertical is at ", value)
left_speed = scale(value, (0, 255), (100, -100))
# React to the left stick horizontal
elif code == 0:
print("The left stick horizontal is at ", value)
# React to the right stick vertical
elif code == 4:
print("The right stick vertical is at ", value)
right_speed = scale(value, (0, 255), (100, -100))
# React to the right stick horizontal
elif code == 3:
print("The right stick horizontal is at ", value)
# React to the Directional pad
if code == 16 and value == -1:
print("The horizontal directional pad is left")
elif code == 16 and value == 1:
print("The horizontal directional pad is right")
elif code == 16 and value == 0:
print("The horizontal directional pad is released")
elif code == 17 and value == -1:
print("The vertical directional pad is up")
elif code == 17 and value == 1:
print("The horizontal directional pad is down")
elif code == 17 and value == 0:
print("The horizontal directional pad is released")
# Set motor speed
left_motor.dc(left_speed)
right_motor.dc(right_speed)
# Read the next event
event = in_file.read(EVENT_SIZE)
in_file.close()
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+15
View File
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
+7
View File
@@ -0,0 +1,7 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false,
"python.languageServer": "None"
}
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.iodevices import AnalogSensor
from pybricks.parameters import Port, Color
from pybricks.tools import wait
class RCXTouchSensor(AnalogSensor):
def pressed(self):
return self.resistance() < 50*1000
ev3 = EV3Brick()
btn = RCXTouchSensor(Port.S1)
while True:
if btn.pressed():
ev3.light.on(Color.ORANGE)
else:
ev3.light.off()
wait(10)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
# Initialize the EV3
ev3 = EV3Brick()
# Draw a rectangle
ev3.screen.draw_box(10, 10, 40, 40)
# Draw a solid rectangle
ev3.screen.draw_box(20, 20, 30, 30, fill=True)
# Draw a rectangle with rounded corners
ev3.screen.draw_box(50, 10, 80, 40, 5)
# Draw a circle
ev3.screen.draw_circle(25, 75, 20)
# Draw a triangle using lines
x1, y1 = 65, 55
x2, y2 = 50, 95
x3, y3 = 80, 95
ev3.screen.draw_line(x1, y1, x2, y2)
ev3.screen.draw_line(x2, y2, x3, y3)
ev3.screen.draw_line(x3, y3, x1, y1)
# Wait some time to look at the shapes
wait(5000)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env pybricks-micropython
import math
from pybricks.hubs import EV3Brick
from pybricks.parameters import Color
from pybricks.tools import wait
from pybricks.media.ev3dev import Font, Image
# Initialize the EV3
ev3 = EV3Brick()
# SPLIT SCREEN ################################################################
# Make a sub-image for the left half of the screen
left = Image(ev3.screen, sub=True, x1=0, y1=0,
x2=ev3.screen.width // 2 - 1, y2=ev3.screen.height - 1)
# Make a sub-image for the right half of the screen
right = Image(ev3.screen, sub=True, x1=ev3.screen.width // 2, y1=0,
x2=ev3.screen.width - 1, y2=ev3.screen.height - 1)
# Use a monospaced font so that text is vertically aligned when we print
right.set_font(Font(size=8, monospace=True))
# Graphing y = sin(x)
def f(x):
return math.sin(x)
for t in range(200):
# Graph on left side
# Scale t to x-axis and compute y values
x0 = (t - 1) * 2 * math.pi / left.width
y0 = f(x0)
x1 = t * 2 * math.pi / left.width
y1 = f(x1)
# Scale y values to screen coordinates
sy0 = (-y0 + 1) * left.height / 2
sy1 = (-y1 + 1) * left.height / 2
# Shift the current graph to the left one pixel
left.draw_image(-1, 0, left)
# Fill the last column with white to erase the previous plot point
left.draw_line(left.width - 1, 0, left.width - 1, left.height - 1, 1, Color.WHITE)
# Draw the new value of the graph in the last column
left.draw_line(left.width - 2, int(sy0), left.width - 1, int(sy1), 3)
# Print every 10th value on right side
if t % 10 == 0:
right.print('{:10.2f}{:10.2f}'.format(x1, y1))
wait(100)
# SPRITE ANIMATION ############################################################
# Copy of screen for double-buffering
buf = Image(ev3.screen)
# Load images from file
bg = Image('background.png')
sprite = Image('sprite.png')
# Number of cells in each sprite animation
NUM_CELLS = 8
# Each cell in the sprite is 75 x 100 pixels
CELL_WIDTH, CELL_HEIGHT = 75, 100
# Get sub-images for each individual cell
# This is more efficient that loading individual images
walk_right = [Image(sprite, sub=True, x1=x * CELL_WIDTH, y1=0,
x2=(x + 1) * CELL_WIDTH - 1, y2=CELL_HEIGHT - 1)
for x in range(NUM_CELLS)]
walk_left = [Image(sprite, sub=True, x1=x * CELL_WIDTH, y1=CELL_HEIGHT,
x2=(x + 1) * CELL_WIDTH - 1, y2=2 * CELL_HEIGHT - 1)
for x in range(NUM_CELLS)]
# Walk from left to right
for x in range(-100, 200, 2):
# Start with the background image
buf.draw_image(0, 0, bg)
# Draw the current sprite - purple is treated as transparent
buf.draw_image(x, 5, walk_right[x // 5 % NUM_CELLS], Color.PURPLE)
# Copy the double-buffer to the screen
ev3.screen.draw_image(0, 0, buf)
# 20 frames per second
wait(50)
# Walk from right to left
for x in range(200, -100, -2):
buf.draw_image(0, 0, bg)
buf.draw_image(x, 5, walk_left[x // 5 % NUM_CELLS], Color.PURPLE)
ev3.screen.draw_image(0, 0, buf)
wait(50)
wait(1000)
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/
+13
View File
@@ -0,0 +1,13 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py"
}
]
}
+6
View File
@@ -0,0 +1,6 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.eol": "\n",
"debug.openDebug": "neverOpen",
"python.linting.enabled": false
}
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.tools import wait
from pybricks.media.ev3dev import Image, ImageFile
# It takes some time to load images from the SD card, so it is best to load
# them once at the beginning of a program like this:
ev3_img = Image(ImageFile.EV3_ICON)
# Initialize the EV3
ev3 = EV3Brick()
# Show an image
ev3.screen.load_image(ev3_img)
# Wait some time to look at the image
wait(5000)
+3
View File
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
.venv/

Some files were not shown because too many files have changed in this diff Show More