Here we go, easy work-around for the faulty lcd.image():
from m5stack import *
buffer = open("/sd/images/test.jpg").read()
lcd.image_buff(lcd.CENTER, lcd.CENTER, buffer)
Here we go, easy work-around for the faulty lcd.image():
from m5stack import *
buffer = open("/sd/images/test.jpg").read()
lcd.image_buff(lcd.CENTER, lcd.CENTER, buffer)
Adding upip
to the firmware image would make developer's live much easier.
How to manually install the urllib.parse
library.
Create folder /upip
and add files upip.py and upip_utarfile.py manually.
Install the library with upip:
%cd /flash/upip
import upip
upip.install("micropython-urllib.parse", "/flash/lib")
To get it working, remove re.py
and ffilib.py
from lib
. Hat-tip to Andreas.
Finally you can encode URL parameters for GET requests:
%cd /flash/lib
import urllib.parse
urllib.parse.urlencode({"a":1, "b": 2})
=> 'a=1&b=2'
In the forum I read that there is some advanced touch/swipe functionality available for the Arduino language.
Will there be high level touch/swipe functions for UIFlow?
I would like to do some photo swiping/scrolling on my Core2, like on a smart phone.
Cheers
Mike
Adding upip
to the firmware image would make developer's live much easier.
How to manually install the urllib.parse
library.
Create folder /upip
and add files upip.py and upip_utarfile.py manually.
Install the library with upip:
%cd /flash/upip
import upip
upip.install("micropython-urllib.parse", "/flash/lib")
To get it working, remove re.py
and ffilib.py
from lib
. Hat-tip to Andreas.
Finally you can encode URL parameters for GET requests:
%cd /flash/lib
import urllib.parse
urllib.parse.urlencode({"a":1, "b": 2})
=> 'a=1&b=2'
I am currently playing around with some web services and libraries, it mostly fails because most of those MicroPython programs require urllib.parse
to be installed, mostly for urlencode()
.
It would be great to get urllib.parse and its dependencies into the base firmware image.
Cheers
Mike
Well, and there is always the option to just strip it down to the basics.
# urlencode.py
_ALWAYS_SAFE = frozenset(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
b'abcdefghijklmnopqrstuvwxyz'
b'0123456789'
b'_.-')
_ALWAYS_SAFE_BYTES = bytes(_ALWAYS_SAFE)
def quote(string, safe='/', encoding=None, errors=None):
"""quote('abc def') -> 'abc%20def'
Each part of a URL, e.g. the path info, the query, etc., has a
different set of reserved characters that must be quoted.
RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists
the following reserved characters.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
"$" | ","
Each of these characters is reserved in some component of a URL,
but not necessarily in all of them.
By default, the quote function is intended for quoting the path
section of a URL. Thus, it will not encode '/'. This character
is reserved, but in typical usage the quote function is being
called on a path where the existing slash characters are used as
reserved characters.
string and safe may be either str or bytes objects. encoding must
not be specified if string is a str.
The optional encoding and errors parameters specify how to deal with
non-ASCII characters, as accepted by the str.encode method.
By default, encoding='utf-8' (characters are encoded with UTF-8), and
errors='strict' (unsupported characters raise a UnicodeEncodeError).
"""
if isinstance(string, str):
if not string:
return string
if encoding is None:
encoding = 'utf-8'
if errors is None:
errors = 'strict'
string = string.encode(encoding, errors)
else:
if encoding is not None:
raise TypeError("quote() doesn't support 'encoding' for bytes")
if errors is not None:
raise TypeError("quote() doesn't support 'errors' for bytes")
return quote_from_bytes(string, safe)
def quote_plus(string, safe='', encoding=None, errors=None):
"""Like quote(), but also replace ' ' with '+', as required for quoting
HTML form values. Plus signs in the original string are escaped unless
they are included in safe. It also does not have safe default to '/'.
"""
# Check if ' ' in string, where string may either be a str or bytes. If
# there are no spaces, the regular quote will produce the right answer.
if ((isinstance(string, str) and ' ' not in string) or
(isinstance(string, bytes) and b' ' not in string)):
return quote(string, safe, encoding, errors)
if isinstance(safe, str):
space = ' '
else:
space = b' '
string = quote(string, safe + space, encoding, errors)
return string.replace(' ', '+')
def quote_from_bytes(bs, safe='/'):
"""Like quote(), but accepts a bytes object rather than a str, and does
not perform string-to-bytes encoding. It always returns an ASCII string.
quote_from_bytes(b'abc def\x3f') -> 'abc%20def%3f'
"""
if not isinstance(bs, (bytes, bytearray)):
raise TypeError("quote_from_bytes() expected bytes")
if not bs:
return ''
if isinstance(safe, str):
# Normalize 'safe' by converting to bytes and removing non-ASCII chars
safe = safe.encode('ascii', 'ignore')
else:
safe = bytes([c for c in safe if c < 128])
if not bs.rstrip(_ALWAYS_SAFE_BYTES + safe):
return bs.decode()
try:
quoter = _safe_quoters[safe]
except KeyError:
_safe_quoters[safe] = quoter = Quoter(safe).__getitem__
return ''.join([quoter(char) for char in bs])
def urlencode(query, doseq=False, safe='', encoding=None, errors=None):
"""Encode a dict or sequence of two-element tuples into a URL query string.
If any values in the query arg are sequences and doseq is true, each
sequence element is converted to a separate parameter.
If the query arg is a sequence of two-element tuples, the order of the
parameters in the output will match the order of parameters in the
input.
The components of a query arg may each be either a string or a bytes type.
When a component is a string, the safe, encoding and error parameters are
sent to the quote_plus function for encoding.
"""
if hasattr(query, "items"):
query = query.items()
else:
# It's a bother at times that strings and string-like objects are
# sequences.
try:
# non-sequence items should not work with len()
# non-empty strings will fail this
if len(query) and not isinstance(query[0], tuple):
raise TypeError
# Zero-length sequences of all types will get here and succeed,
# but that's a minor nit. Since the original implementation
# allowed empty dicts that type of behavior probably should be
# preserved for consistency
except TypeError:
# ty, va, tb = sys.exc_info()
raise TypeError("not a valid non-string sequence "
"or mapping object")#.with_traceback(tb)
l = []
if not doseq:
for k, v in query:
if isinstance(k, bytes):
k = quote_plus(k, safe)
else:
k = quote_plus(str(k), safe, encoding, errors)
if isinstance(v, bytes):
v = quote_plus(v, safe)
else:
v = quote_plus(str(v), safe, encoding, errors)
l.append(k + '=' + v)
else:
for k, v in query:
if isinstance(k, bytes):
k = quote_plus(k, safe)
else:
k = quote_plus(str(k), safe, encoding, errors)
if isinstance(v, bytes):
v = quote_plus(v, safe)
l.append(k + '=' + v)
elif isinstance(v, str):
v = quote_plus(v, safe, encoding, errors)
l.append(k + '=' + v)
else:
try:
# Is this a sufficient test for sequence-ness?
x = len(v)
except TypeError:
# not a sequence
v = quote_plus(str(v), safe, encoding, errors)
l.append(k + '=' + v)
else:
# loop over the sequence
for elt in v:
if isinstance(elt, bytes):
elt = quote_plus(elt, safe)
else:
elt = quote_plus(str(elt), safe, encoding, errors)
l.append(k + '=' + elt)
return '&'.join(l)
Then we can finally do a nicer GET with parameters:
import urequests
from urlencode import urlencode
url = 'http://server.tld/path/to'
params = {'key1': 'value1', 'key2': 'value2'}
if params:
url = url.rstrip('?') + '?' + urlencode(params, doseq=True)
print(url)
response = urequests.get(url)
Thanks, @ksprayberry, I can manually transfer files. I just thought there was a upip
or something on the device which can be used from the REPL.
I would like to do a simple HTTP GET requests with key-value params.
This seems not supported by urequests, I found a recommended work-around:
import urequests
from urllib.parse import urlencode
def get(url, params=None, **kw):
if params:
url = url.rstrip('?') + '?' + urlencode(params, doseq=True)
return urequests.get(url, **kw)
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
res = get('http://httpbin.org/get', payload)
print(res.json())
Sadly urllib.parse
from micropython-lib is not included in M5Stack MicroPython.
How can I install a MicroPython library onto my Core2? I am currently using Thonny IDE.
Does Core2 support touch event handlers in MicroPython?
I would like to define my own touch interface:
So far I only found the M5Btn class, but I can not use it to define transparent touch tiles.
from m5stack import *
from m5stack_ui import *
from uiflow import *
screen = M5Screen()
screen.clean_screen()
screen.set_screen_bg_color(0xFFFFFF)
touch_button0 = M5Btn(text=None, x=0, y=0, w=100, h=80, bg_c=None, text_c=None, font=None, parent=None)
def touch_button0_pressed():
# global params
pass
touch_button0.pressed(touch_button0_pressed)
I tried to overwrite the button with my touch tiles, but after press the button is shown.
lcd.fillRect( 0, 0, 100, 80, 0xff0000 )
lcd.fillRect( 100, 0, 120, 80, 0x00ff00 )
lcd.fillRect( 220, 0, 100, 80, 0x0000ff )
lcd.fillRect( 0, 80, 100, 80, 0xaa0000 )
lcd.fillRect( 100, 80, 120, 80, 0x00aa00 )
lcd.fillRect( 220, 80, 100, 80, 0x0000aa )
lcd.fillRect( 0, 160, 100, 80, 0x550000 )
lcd.fillRect( 100, 160, 120, 80, 0x005500 )
lcd.fillRect( 220, 160, 100, 80, 0x000055 )
Or do I need to do this manually in a loop?
import time
from m5stack import *
def tile(x,y):
qx = 0
qy = 0
if x>=0 and x<100: qx = 1
if x>=100 and x<220: qx = 2
if x>=220 and x<320: qx = 3
if y>=0 and y<80: qy = 0
if y>=80 and y<160: qy = 3
if y>=160 and y<240: qy = 6
return qx + qy
def action(q):
if q == 0: lcd.clear(0xFFFFFF)
if q == 1: lcd.fillRect( 0, 0, 100, 80, 0xff0000 )
if q == 2: lcd.fillRect( 100, 0, 120, 80, 0x00ff00 )
if q == 3: lcd.fillRect( 220, 0, 100, 80, 0x0000ff )
if q == 4: lcd.fillRect( 0, 80, 100, 80, 0xaa0000 )
if q == 5: lcd.fillRect( 100, 80, 120, 80, 0x00aa00 )
if q == 6: lcd.fillRect( 220, 80, 100, 80, 0x0000aa )
if q == 7: lcd.fillRect( 0, 160, 100, 80, 0x550000 )
if q == 8: lcd.fillRect( 100, 160, 120, 80, 0x005500 )
if q == 9: lcd.fillRect( 220, 160, 100, 80, 0x000055 )
def loop():
x = -1
y = -1
while True:
if touch.status() == True:
t = touch.read()
tx = t[0]
ty = t[1]
if x != tx and y != ty:
x = tx
y = ty
q = tile(x, y)
action(q);
else:
x = -1
y = -1
action(0)
time.sleep(0.05)
loop()
Here we go, easy work-around for the faulty lcd.image():
from m5stack import *
buffer = open("/sd/images/test.jpg").read()
lcd.image_buff(lcd.CENTER, lcd.CENTER, buffer)
Here we go, easy work-around the faulty lcd.image():
from m5stack import *
buffer = open("/sd/images/test.jpg").read()
lcd.image_buff(lcd.CENTER, lcd.CENTER, buffer)
I would prefer to have a stable API for all devices. Current situation makes re-use of code complicated.
Someone could write a wrapper API to cover the differences ;-)
Hi, I think this is mostly a community-driven forum, so it is other developers that can answer.
I am not sure that any staff is speaking Russian and participating in the Russian-language forum.