pull/10324/merge
Wolf Paulus 2024-03-16 09:38:58 +08:00 zatwierdzone przez GitHub
commit d7f2abc43b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
14 zmienionych plików z 844 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,23 @@
{
"deploy": [
"../deploy.md"
],
"docs": "",
"features": [
"Battery Charging",
"Feather",
"RGB LED",
"STEMMA QT/QWIIC",
"BLE",
"WiFi"
],
"id": "pyBox",
"images": [
"pyBox.jpg"
],
"mcu": "esp32",
"product": "pyBox",
"thumbnail": "https://wolfpaulus.com/content/pyBox.jpg",
"url": "https://wolfpaulus.com/pyBox",
"vendor": "Techcasita Productions"
}

Wyświetl plik

@ -0,0 +1,2 @@
The following files for the SparkFun Thing Plus – ESP32 WROOM (USB-C) paired with the SparkFun 16×2 SerLCD – RGB Text (Qwiic).
This firmware is compiled using ESP-IDF v4.4.

Wyświetl plik

@ -0,0 +1,2 @@
include("$(PORT_DIR)/boards/manifest.py")
freeze("modules")

Wyświetl plik

@ -0,0 +1,148 @@
"""
NeoPixel, BlueLED, SDDrive, WiFi for MicroPython on SparkFun Thing Plus
Author: wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
from machine import freq, Pin, SDCard, Signal, RTC
from utime import sleep
from network import WLAN, STA_IF
from neopixel import NeoPixel
from uos import mount
from pybox_btn import Button
from collections import OrderedDict
_BTN_UP_PIN = const(27)
_BTN_DN_PIN = const(33)
_TURBO_SPEED = const(240000000)
_NORMAL_SPEED = const(160000000)
_BLUE_LED_PIN = const(13)
_NEO_PIN = const(2)
class Neo:
"""
NeoPixel
"""
def __init__(self, pin: int = 2):
self.neo = NeoPixel(Pin(pin, Pin.OUT, value=False), 1)
def color(self, r: int = 255, g: int = 255, b: int = 255):
self.neo[0] = (r, g, b)
self.neo.write()
def get_color(self) -> (int, int, int):
return self.neo[0]
def off(self) -> None:
self.neo[0] = (0, 0, 0)
self.neo.write()
def turbo(on: bool = True) -> None:
"""
Switch ESP's clock speed
:param on: 240MHz is True else, defaulting to 160MHz
:return: None
"""
freq(_TURBO_SPEED if on else _NORMAL_SPEED)
def mount_sd(directory: str = "/sd") -> None:
"""
Define removable storage media - secure digital memory card
"""
sd = SDCard(slot=2, width=1, cd=None, wp=None, sck=18, miso=19, mosi=23, cs=5, freq=40000000)
mount(sd, directory)
def connect(wifi_networks: list) -> bool:
"""
Connect to Wifi router or become an Access Point
:param wifi_networks: list of tuples [(ssid, password),..]
:return: True if connected
"""
global hostname, ip_addr
conn = False
while not conn:
for ssid, pw in wifi_networks:
print(ssid)
sta_if = WLAN(STA_IF)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect(ssid, pw)
# sta_if.config(dhcp_hostname=profile.HostName)
for i in range(2, 8):
sta_if = WLAN(STA_IF)
if sta_if.isconnected():
conn = True
ip_addr = sta_if.ifconfig()[0]
hostname = sta_if.config("dhcp_hostname")
break
else:
sleep(i)
if conn:
break
return conn
def is_connected() -> bool:
"""
:return: True is connected to WiFi
"""
return WLAN(STA_IF).isconnected()
def set_system_time(d: dict) -> None:
"""
Set the Systemtime
:param d: dictionary
:return:
"""
RTC().datetime((d["year"], d["month"], d["day"], 0, d["hour"], d["minute"], d["seconds"], 0))
def rgb_color() -> (int, int, int):
"""
RGB color generator (r,g,b in the range 0..255)
:return: (r,g,b all in the range 0..255)
"""
for i in range(1, 86):
yield 255 - i * 3, 0, i * 3
for i in range(1, 86):
yield 0, i * 3, 255 - i * 3
for i in range(1, 86):
yield i * 3, 255 - i * 3, 0
palette = OrderedDict(
[
# red
("Auriga", (255, 0, 63)),
("Antares", (255, 0, 0)),
# orange
("Jupiter", (255, 32, 0)),
("Proxima", (191, 128, 0)),
# gray
("Sirius", (255, 255, 255)),
("Vega", (127, 127, 191)),
# green
("Nebula", (0, 255, 0)),
("Kepler", (0, 127, 63)),
("Uranus", (0, 191, 255)),
# blue
("Rigel", (31, 31, 255)),
("Medusa", (127, 0, 255)),
("Orion", (255, 31, 255)),
]
)
blue_led = Signal(Pin(_BLUE_LED_PIN, mode=Pin.OUT, value=False), invert=False)
blue_led.off()
neo = Neo(_NEO_PIN)
neo.color(0, 0, 0)
btn_up = Button(_BTN_UP_PIN)
btn_dn = Button(_BTN_DN_PIN)
hostname = ""
ip_addr = "0.0.0.0"

Wyświetl plik

@ -0,0 +1,70 @@
"""
Capacitive Touch Buttons with Press and Long-Press detection
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from machine import Pin, TouchPad
from utime import ticks_ms, ticks_diff
import pybox_ct as ct
class Button(TouchPad):
"""Capacitive Touch Button"""
def __init__(
self,
pin: int,
on_press: callable = None,
on_long_press: callable = None,
threshold: int = 600,
hold_ms: int = 500,
freq_ms: int = 100,
):
"""
:param pin: port pin this button is connected to
:param on_press: function to be called on touch
:param on_long_press: function to be called on long touch
:param threshold: capacitive touch value that qualifies as a touch
:param hold_ms: number of ms button needs to be touch to register a long touch
:param freq_ms: number of ms between checks
"""
super().__init__(Pin(pin))
self.on_press = on_press
self.on_long_press = on_long_press
self._threshold = threshold
self._hold = hold_ms
self._freq = freq_ms
self._acted = False
self._started = 0
self._active = True
def set_actions(self, on_press: callable = None, on_long_press: callable = None):
self.on_press = on_press
self.on_long_press = on_long_press
def check(self) -> None:
"""timer triggered"""
if self._active and (self.on_press or self.on_long_press):
v = self.read()
if v < self._threshold: # button currently touched
if not self._started:
self._started = ticks_ms()
elif self._hold < ticks_diff(ticks_ms(), self._started): # long press detected
if not self._acted:
self._active = False
self.on_long_press()
self._active = self._acted = True
elif self._started: # button was released
if not self._acted:
self._active = False
self.on_press()
self._active = True
else:
self._acted = False
self._started = 0
def enable(self):
ct.register((self.check, self._freq))
def disable(self):
ct.unregister((self.check, self._freq))

Wyświetl plik

@ -0,0 +1,56 @@
"""
ct - Central Timer
One timer will be used for all of pyBox system calls, leaving remaining three for custom code
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
from machine import Timer
import pybox_log as log
_TIMER_ID = const(0)
_TICK_MS = const(1)
MIN_FREQ = const(1000 // _TICK_MS * 60 * 60) # about 1 hour
MAX_FREQ = const(_TICK_MS)
def process(_) -> None:
"""
this is called every ${frequency}-th of a second and will call every callback that is due.
:return: None
"""
global _counter
_counter = _counter + 1 if _counter < MIN_FREQ else 1 # 1..3_600_000
for t in _tasks:
if _counter % t[1] == 0:
t[0]()
def register(task: ()) -> None:
"""
Registers a callback and call frequency. The callback should have no parameters
and the frequency should be in MAX_FREQ..MIN_FREQ range
:param task: callback,freq
:return: None
"""
_tasks.append(task)
def unregister(task: (callable, int)) -> None:
"""
Unregisters a previously registered task
:param task: callback,freq
:return: None
"""
for i in range(len(_tasks) - 1, -1, -1):
if _tasks[i][0].__name__ == task[0].__name__:
_tasks.pop(i)
break
else:
log.log(log.ERROR, f"Could not unregister {task[0].__name__}")
_counter = 0
_tasks = []
_timer = Timer(_TIMER_ID)
_timer.init(mode=Timer.PERIODIC, period=_TICK_MS, callback=process)

Wyświetl plik

@ -0,0 +1,32 @@
"""
fg - Fuel Gauge
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
import pybox_i2c as i2c
DEFAULT_ADDRESS = const(0x36)
_MAX17048_VCELL = const(0x02)
_MAX17048_SOC = const(0x04)
def is_connected(address=DEFAULT_ADDRESS):
"""
Determine if a device is connected to the system.
:return: True if the device is connected, otherwise False.
:rtype: bool
"""
return i2c.is_device_connected(address)
def voltage(address=DEFAULT_ADDRESS) -> float:
"""Current Voltage"""
raw = i2c.read16(address, _MAX17048_VCELL)
return raw * 78.125 / 1_000_000
def remaining(address=DEFAULT_ADDRESS) -> int:
"""remaining capacity in percentage"""
raw = i2c.read16(address, _MAX17048_SOC)
return raw // 256

Wyświetl plik

@ -0,0 +1,97 @@
"""
Communicate with devices on the i2c bus (i2c / Qwiic connector)
0x72 Sparkfun 16x2 LCD https://www.sparkfun.com/products/16397
0x36 MAX17048 fuel gauge https://cdn.sparkfun.com/assets/b/b/2/c/b/MAX17048.pdf
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
from machine import Pin, I2C
_I2C_SDA = const(21)
_I2C_SCL = const(22)
_FREQ = const(400000)
def write_bytes(address: int, ba: bytearray) -> None:
"""Sends a bytearray to the given device address
:param address: I2C address of the device to write to
:param ba: bytes to write
:return: None
"""
_i2c.writeto(address, ba)
def write_byte(address: int, data: int) -> None:
"""Sends a single byte to the device
:param address: I2C address of the device to write to
:param data: the data will be cast to a byte and then send.
:return: None
"""
ba = bytearray(1)
ba[0] = data
_i2c.writeto(address, ba)
def write_cmd(address: int, command: int, value: int) -> None:
"""Sends two bytes, e.g. a command and a parameter
:param address: I2C address of the device to write to
:param command: The "command" or register
:param value: The byte to write to the I2C bus
:return: None
"""
ba = bytearray(2)
ba[0] = command
ba[1] = value
write_bytes(address, ba)
def write_block(address: int, command: int, values: [int]) -> None:
"""Sends a command byte and a data list
:param address: I2C address of the device to write to
:param command: The "command" or register
:param values: a list of ints (cast to bytes) to write on the I2C bus.
:return: None
"""
ba = bytearray(len(values) + 1)
ba[0] = command
for i in range(len(values)):
ba[i + 1] = values[i]
write_bytes(address, ba)
def scan() -> []:
"""
Scan the i2c bus for devices
:return: list of device ids
"""
return _i2c.scan()
def is_device_connected(address: int) -> bool:
"""
:param address: The I2C address of the device to to look for
:return: True, if the device is on the bus
"""
devices = scan()
if address in devices:
try:
write_byte(address, 0x0)
return True
except Exception as ee:
print("Error connecting to Device: %X, %s" % (address, ee))
pass
return False
def read16(address: int, register: int) -> int:
"""
:param address: The I2C address of the device to to look for
:param register: int
:return: register value
"""
buffer = _i2c.readfrom_mem(address, register, 2)
return buffer[0] << 8 | buffer[1]
_i2c = I2C(0, sda=Pin(_I2C_SDA), scl=Pin(_I2C_SCL), freq=_FREQ)

Wyświetl plik

@ -0,0 +1,315 @@
"""
Accessing SparkFun's 16x2 SerLCD - RGB Text via i2c
https://www.sparkfun.com/products/16397
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
from utime import sleep_ms
import pybox_i2c as i2c
import pybox_ct as ct
_DEFAULT_ADDRESS = const(0x72)
_LCD_DISPLAYCONTROL = const(0x08)
_LCD_ENTRYMODESET = const(0x04)
_LCD_DISPLAYON = const(0x04)
_LCD_DISPLAYOFF = const(0x00)
_LCD_CURSORON = const(0x02)
_LCD_CURSOROFF = const(0x00)
_LCD_BLINKON = const(0x01)
_LCD_BLINKOFF = const(0x00)
_LCD_ENTRYRIGHT = const(0x00)
_LCD_ENTRYLEFT = const(0x02)
_LCD_ENTRYSHIFTINCREMENT = const(0x01)
_LCD_ENTRYSHIFTDECREMENT = const(0x00)
_LCD_SETDDRAMADDR = const(0x80)
_LCD_RETURNHOME = const(0x02)
_SPECIAL_COMMAND = const(0xFE) # Magic number for sending a special command
_SETTING_COMMAND = const(0x7C) # Command to change settings: baud, lines, width,..
_SET_RGB_COMMAND = const(0x2B) # Command to set backlight RGB value
_ENABLE_SYSTEM_MESSAGE_DISPLAY = const(0x2E) # Command to enable system messages being displayed
_DISABLE_SYSTEM_MESSAGE_DISPLAY = const(0x2F) # Command to disable system messages being displayed
_ENABLE_SPLASH_DISPLAY = const(0x30) # Command to enable splash screen at power on
_DISABLE_SPLASH_DISPLAY = const(0x31) # Command to disable splash screen at power on
_SAVE_CURRENT_DISPLAY_AS_SPLASH = const(0x0A) # Command to save current text on display as splash
_CLEAR_COMMAND = const(0x2D) # Command to clear and home the display
_CONTRAST_COMMAND = const(0x18) # Command to change the contrast setting
_MAX_ROWS = const(2)
_MAX_COLUMNS = const(16)
def special_command(command, count=1) -> None:
"""
Send one (or multiple) special commands to the display. Used by other functions.
:param command: Command to send (a single byte)
:param count: Number of times to send the command (if ommited, then default is once)
:return: Returns true if the I2C write was successful, otherwise False.
:rtype: bool
"""
for i in range(count):
i2c.write_cmd(address, _SPECIAL_COMMAND, command)
sleep_ms(50)
def command(command) -> None:
"""
Send one setting command to the display. Used by other functions.
:param command: Command to send (a single byte)
:return: Returns true if the I2C write was successful, otherwise False.
:rtype: bool
"""
i2c.write_cmd(address, _SETTING_COMMAND, command)
def is_connected() -> bool:
"""
Determine if a device is connected to the system.
:return: True if the device is connected, otherwise False.
:rtype: bool
"""
return i2c.is_device_connected(address)
def enable_system_messages() -> None:
"""
Enable system messages
:return: Returns true if the I2C write was successful, otherwise False.
"""
command(_ENABLE_SYSTEM_MESSAGE_DISPLAY)
sleep_ms(10)
def disable_system_messages() -> None:
"""
Disable system messages
:return: Returns true if the I2C write was successful, otherwise False.
"""
command(_DISABLE_SYSTEM_MESSAGE_DISPLAY)
sleep_ms(10)
def enable_splash() -> None:
"""
Enable splash screen at power on
:return: Returns true if the I2C write was successful, otherwise False.
"""
command(_ENABLE_SPLASH_DISPLAY)
sleep_ms(10)
def disable_splash() -> None:
"""
Disable splash screen at power on
:return: Returns true if the I2C write was successful, otherwise False.
"""
command(_DISABLE_SPLASH_DISPLAY)
sleep_ms(10)
def save_splash() -> None:
"""
Save the current display as the splash. Saves whatever is currently being displayed into EEPROM
This will be displayed at next power on as the splash screen
:return: Returns true if the I2C write was successful, otherwise False.
"""
command(_SAVE_CURRENT_DISPLAY_AS_SPLASH)
sleep_ms(10)
def set_backlight(r: int, g: int, b: int) -> None:
"""
Set backlight with no LCD messages or delays
:param r: red backlight value 0-255
:param g: green backlight value 0-255
:param b: blue backlight value 0-255
:return: Returns true if the I2C write was successful, otherwise False.
"""
# create a block of data bytes to send to the screen
# This will include the SET_RGB_COMMAND, and three bytes of backlight values
block = [0, 1, 2, 3]
block[0] = _SET_RGB_COMMAND # command
block[1] = r
block[2] = g
block[3] = b
# send the complete bytes (address, settings command , rgb command , red byte, green byte, blue byte)
i2c.write_block(_DEFAULT_ADDRESS, _SETTING_COMMAND, block)
sleep_ms(10)
def display():
"""
Turn the display on quickly.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl |= _LCD_DISPLAYON
return special_command(_LCD_DISPLAYCONTROL | displayControl)
def no_display() -> None:
"""
Turn the display off quickly.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl &= _LCD_DISPLAYON
special_command(_LCD_DISPLAYCONTROL | displayControl)
def blink() -> None:
"""
Turn the blink cursor on.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl |= _LCD_BLINKON
special_command(_LCD_DISPLAYCONTROL | displayControl)
def no_blink() -> None:
"""
Turn the blink cursor off.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl &= ~_LCD_BLINKON
special_command(_LCD_DISPLAYCONTROL | displayControl)
def cursor() -> None:
"""
Turn the underline cursor on.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl |= _LCD_CURSORON
special_command(_LCD_DISPLAYCONTROL | displayControl)
def no_cursor() -> None:
"""
Turn the underline cursor off.
:return: Returns true if the I2C write was successful, otherwise False.
"""
global displayControl
displayControl &= ~_LCD_CURSORON
special_command(_LCD_DISPLAYCONTROL | displayControl)
def set_cursor(col, row) -> None:
"""
Set the cursor position to a particular column and row.
:param col: The column postion (0-19)
:param row: The row postion (0-3)
:return: Returns true if the I2C write was successful, otherwise False.
"""
row_offsets = [0x00, 0x40, 0x14, 0x54]
# keep variables in bounds
row = max(0, row) # row cannot be less than 0
row = min(row, (_MAX_ROWS - 1)) # row cannot be greater than max rows
# construct the cursor "command"
command = _LCD_SETDDRAMADDR | (col + row_offsets[row])
# send the complete bytes (special command + command)
special_command(command)
def set_contrast(contrast) -> None:
"""
Set the contrast of the LCD screen (0-255)
:param contrast: The new contrast value (0-255)
:return: Returns true if the I2C write was successful, otherwise False.
"""
# To set the contrast we need to send 3 bytes:
# (1) SETTINGS_COMMAND
# (2) CONTRAST_COMMAND
# (3) contrast value
# To do this, we are going to use writeBlock(),
# so we need our "block of bytes" to include
# CONTRAST_COMMAND and contrast value
block = [_CONTRAST_COMMAND, contrast]
# send the complete bytes (address, settings command , contrast command, contrast value)
i2c.write_block(address, _SETTING_COMMAND, block)
sleep_ms(10)
def home() -> None:
"""
Send the home command to the display.
This returns the cursor to return to the beginning of the display,
without clearing the display.
:return: Returns true if the I2C write was successful, otherwise False.
"""
special_command(_LCD_RETURNHOME)
sleep_ms(10)
def clear_screen() -> None:
"""
Sends the command to clear the screen
:return: Returns true if the I2C write was successful, otherwise False.
"""
print("", "") # this should unregister potentially running scroll tasks
set_backlight(255, 255, 255)
set_contrast(0)
command(_CLEAR_COMMAND)
sleep_ms(10)
def print(row0: str = None, row1: str = None) -> None:
"""
Outputs the given rows.
If a provided row in None, its current content will remain, i.e. use "" to clear that row's content
If a provided row's content is longer than the display, the content will scroll
Only a not scrolling row will be immediately updated
:param row0
:param row1
:return: None
"""
global scrolling
update = row0 is not None or row1 is not None
if update:
content = [row0, row1]
for r in range(_MAX_ROWS):
if content[r] is not None:
if len(content[r]) > _MAX_COLUMNS: # add a gap for scrolling
content_buffer[r] = content[r] + 3 * " "
else: # fill the row
content_buffer[r] = content[r] + (_MAX_COLUMNS - len(content[r])) * " "
longest = max([len(content_buffer[0]), len(content_buffer[1])])
if longest > _MAX_COLUMNS: # need_to_scroll
if not scrolling:
scrolling = True
ct.register((print, scroll_speed))
elif scrolling:
ct.unregister((print, scroll_speed))
scrolling = False
s = ""
for r in range(_MAX_ROWS):
if len(content_buffer[r]) > _MAX_COLUMNS and not update: # scroll content
if chr(126) not in content_buffer[r]: # move 1st char to the end
content_buffer[r] = content_buffer[r][1:] + content_buffer[r][0]
else: # (->) in str .. move last char to the start
content_buffer[r] = content_buffer[r][-1] + content_buffer[r][0:-1]
s += content_buffer[r][:_MAX_COLUMNS]
i2c.write_bytes(address, bytes(s, "utf-8"))
if update:
sleep_ms(50)
displayControl = _LCD_DISPLAYON | _LCD_CURSOROFF | _LCD_BLINKOFF
displayMode = _LCD_ENTRYLEFT | _LCD_ENTRYSHIFTDECREMENT
content_buffer = [" " * _MAX_COLUMNS, " " * _MAX_COLUMNS]
scrolling = False
address = _DEFAULT_ADDRESS
scroll_speed = 350 # 250 .. 450 looks OK
special_command(_LCD_DISPLAYCONTROL | displayControl)
special_command(_LCD_ENTRYMODESET | displayMode)
disable_system_messages()
clear_screen()

Wyświetl plik

@ -0,0 +1,34 @@
"""
Minimal Logger
Author: Wolf Paulus wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from micropython import const
from utime import localtime
from uos import remove
CRITICAL = const(50)
ERROR = const(40)
WARNING = const(30)
INFO = const(20)
DEBUG = const(10)
LOG_FILE = "/log.txt"
log_level = WARNING
def reset() -> None:
try:
remove(LOG_FILE)
except:
pass
def log(level: int, msg: str):
try:
if level >= log_level:
with open(LOG_FILE, "a") as file:
file.write(f"{level} : {localtime()} : {msg}\n")
except:
pass

Wyświetl plik

@ -0,0 +1,39 @@
"""
Fetch Time Zone info from timeapi.io
Author: wolf@paulus.com
MIT license; Copyright (c) 2022 wolfpaulus.com
"""
from urequests import request
from utime import sleep
import pybox_log as log
def get_time_stamp(tz: str) -> dict:
"""
Fetches the current time stamp at a given time zone:
:param tz: str
:return: {
"year": 2022,
"month": 12,
"day": 18,
"hour": 11,
"minute": 4,
"seconds": 2,
"milliSeconds": 692,
"dateTime": "2022-12-18T11:04:02.6927298",
"date": "12/18/2022",
"time": "11:04",
"timeZone": "America/Phoenix",
"dayOfWeek": "Sunday",
"dstActive": false
}
"""
url = f"https://timeapi.io/api/Time/current/zone?timeZone={tz}"
headers = {"accept": "application/json"}
for i in range(1, 4):
try:
return request("GET", url, headers=headers).json()
except Exception as e:
log.log(log.ERROR, str(e))
sleep(i)
return {}

Wyświetl plik

@ -0,0 +1,7 @@
set(IDF_TARGET esp32)
set(SDKCONFIG_DEFAULTS
boards/sdkconfig.base
boards/sdkconfig.ble
boards/PYBOX/sdkconfig.board
)
set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py)

Wyświetl plik

@ -0,0 +1,2 @@
#define MICROPY_HW_BOARD_NAME "pyBox"
#define MICROPY_HW_MCU_NAME "ESP32"

Wyświetl plik

@ -0,0 +1,17 @@
CONFIG_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_AFTER_NORESET=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-16MiB.csv"
# Network name
CONFIG_LWIP_LOCAL_HOSTNAME="pyBox"