mirror of
https://github.com/pybricks/pybricks-api.git
synced 2026-09-12 01:24:17 +00:00
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:
committed by
laurensvalk
parent
30e87695ea
commit
b0ffb24a2e
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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]
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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!')
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
venv/
|
||||
+13
@@ -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
@@ -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
@@ -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,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/
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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 |
@@ -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 |
@@ -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)
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
+13
@@ -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
@@ -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
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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,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"
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
+20
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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,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,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)
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
venv/
|
||||
+13
@@ -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
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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,)))
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
venv/
|
||||
+13
@@ -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
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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()
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
+13
@@ -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"
|
||||
]
|
||||
}
|
||||
Vendored
+15
@@ -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
@@ -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"
|
||||
}
|
||||
@@ -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()
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
+13
@@ -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
@@ -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,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"
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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)
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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 |
@@ -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 |
@@ -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"
|
||||
]
|
||||
}
|
||||
+14
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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,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)
|
||||
@@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user