Merge branch 'master' into master

This commit is contained in:
Anne Barela 2020-07-03 20:01:22 -04:00 committed by GitHub
commit 0288306c32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1456 additions and 12 deletions

View file

@ -0,0 +1,295 @@
/*
ESP32BootROM - part of the Firmware Updater for the
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
Copyright (c) 2018 Arduino SA. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ESP32BootROM.h"
extern ESP32BootROMClass ESP32BootROM;
//#define DEBUG 1
ESP32BootROMClass::ESP32BootROMClass(HardwareSerial& serial, int gpio0Pin, int resetnPin) :
_serial(&serial),
_gpio0Pin(gpio0Pin),
_resetnPin(resetnPin)
{
}
int ESP32BootROMClass::begin(unsigned long baudrate)
{
_serial->begin(115200);
pinMode(_gpio0Pin, OUTPUT);
pinMode(_resetnPin, OUTPUT);
digitalWrite(_gpio0Pin, LOW);
digitalWrite(_resetnPin, LOW);
delay(10);
digitalWrite(_resetnPin, HIGH);
delay(100);
int synced = 0;
for (int retries = 0; !synced && (retries < 5); retries++) {
synced = sync();
}
if (!synced) {
return 0;
}
#if defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(ARDUINO_AVR_UNO_WIFI_REV2)
(void)baudrate;
#else
if (baudrate != 115200) {
if (!changeBaudrate(baudrate)) {
return 0;
}
delay(100);
_serial->end();
_serial->begin(baudrate);
}
#endif
if (!spiAttach()) {
return 0;
}
return 1;
}
void ESP32BootROMClass::end() {
_serial->end();
}
int ESP32BootROMClass::sync()
{
const uint8_t data[] = {
0x07, 0x07, 0x12, 0x20,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
};
command(0x08, data, sizeof(data));
int results[8];
for (int i = 0; i < 8; i++) {
results[i] = response(0x08, 100);
}
return (results[0] == 0);
}
int ESP32BootROMClass::changeBaudrate(unsigned long baudrate)
{
const uint32_t data[2] = {
baudrate,
0
};
command(0x0f, data, sizeof(data));
return (response(0x0f, 3000) == 0);
}
int ESP32BootROMClass::spiAttach()
{
const uint8_t data[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
command(0x0d, data, sizeof(data));
return (response(0x0d, 3000) == 0);
}
int ESP32BootROMClass::beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize) {
const uint32_t data[4] = {
size,
size / chunkSize,
chunkSize,
offset
};
command(0x02, data, sizeof(data));
_flashSequenceNumber = 0;
_chunkSize = chunkSize;
return (response(0x02, 120000) == 0);
}
int ESP32BootROMClass::dataFlash(const void* data, uint32_t length)
{
uint32_t cmdData[4 + (_chunkSize / 4)];
cmdData[0] = length;
cmdData[1] = _flashSequenceNumber++;
cmdData[2] = 0;
cmdData[3] = 0;
memcpy(&cmdData[4], data, length);
if (length < _chunkSize) {
memset(&cmdData[4 + (length / 4)], 0xff, _chunkSize - length);
}
command(0x03, cmdData, sizeof(cmdData));
return (response(0x03, 3000) == 0);
}
int ESP32BootROMClass::endFlash(uint32_t reboot) {
const uint32_t data[1] = {
reboot
};
command(0x04, data, sizeof(data));
return (response(0x04, 3000) == 0);
}
int ESP32BootROMClass::md5Flash(uint32_t offset, uint32_t size, uint8_t* result)
{
const uint32_t data[4] = {
offset,
size,
0,
0
};
command(0x13, data, sizeof(data));
uint8_t asciiResult[32];
if (response(0x13, 3000, asciiResult) != 0) {
return 0;
}
char temp[3] = { 0, 0, 0 };
for (int i = 0; i < 16; i++) {
temp[0] = asciiResult[i * 2];
temp[1] = asciiResult[i * 2 + 1];
result[i] = strtoul(temp, NULL, 16);
}
return 1;
}
void ESP32BootROMClass::command(int opcode, const void* data, uint16_t length)
{
uint32_t checksum = 0;
if (opcode == 0x03) {
checksum = 0xef; // seed
for (uint16_t i = 16; i < length; i++) {
checksum ^= ((const uint8_t*)data)[i];
}
}
_serial->write(0xc0);
_serial->write((uint8_t)0x00); // direction
_serial->write(opcode);
_serial->write((uint8_t*)&length, sizeof(length));
writeEscapedBytes((uint8_t*)&checksum, sizeof(checksum));
writeEscapedBytes((uint8_t*)data, length);
_serial->write(0xc0);
#ifdef ARDUINO_SAMD_MKRVIDOR4000
// _serial->flush(); // doesn't work!
#else
_serial->flush();
#endif
}
int ESP32BootROMClass::response(int opcode, unsigned long timeout, void* body)
{
uint8_t data[10 + 256];
uint16_t index = 0;
uint8_t responseLength = 4;
for (unsigned long start = millis(); (index < (uint16_t)(10 + responseLength)) && (millis() - start) < timeout;) {
if (_serial->available()) {
data[index] = _serial->read();
if (index == 3) {
responseLength = data[index];
}
index++;
}
}
#ifdef DEBUG
if (index) {
for (int i = 0; i < index; i++) {
byte b = data[i];
if (b < 0x10) {
Serial.print('0');
}
Serial.print(b, HEX);
Serial.print(' ');
}
Serial.println();
}
#endif
if (index != (uint16_t)(10 + responseLength)) {
return -1;
}
if (data[0] != 0xc0 || data[1] != 0x01 || data[2] != opcode || data[responseLength + 5] != 0x00 || data[responseLength + 6] != 0x00 || data[responseLength + 9] != 0xc0) {
return -1;
}
if (body) {
memcpy(body, &data[9], responseLength - 4);
}
return data[responseLength + 5];
}
void ESP32BootROMClass::writeEscapedBytes(const uint8_t* data, uint16_t length)
{
uint16_t written = 0;
while (written < length) {
uint8_t b = data[written++];
if (b == 0xdb) {
_serial->write(0xdb);
_serial->write(0xdd);
} else if (b == 0xc0) {
_serial->write(0xdb);
_serial->write(0xdc);
} else {
_serial->write(b);
}
}
}

View file

@ -0,0 +1,56 @@
/*
ESP32BootROM - part of the Firmware Updater for the
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
Copyright (c) 2018 Arduino SA. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
class ESP32BootROMClass {
public:
ESP32BootROMClass(HardwareSerial& hwSerial, int gpio0Pin, int resetnPin);
int begin(unsigned long baudrate);
void end();
int beginFlash(uint32_t offset, uint32_t size, uint32_t chunkSize);
int dataFlash(const void* data, uint32_t length);
int endFlash(uint32_t reboot);
int md5Flash(uint32_t offset, uint32_t size, uint8_t* result);
private:
int sync();
int changeBaudrate(unsigned long baudrate);
int spiAttach();
void command(int opcode, const void* data, uint16_t length);
int response(int opcode, unsigned long timeout, void* body = NULL);
void writeEscapedBytes(const uint8_t* data, uint16_t length);
private:
HardwareSerial* _serial;
int _gpio0Pin;
int _resetnPin;
uint32_t _flashSequenceNumber;
uint32_t _chunkSize;
};
extern ESP32BootROMClass ESP32BootROM;

View file

@ -0,0 +1,138 @@
/*
FirmwareUpdater - Firmware Updater for the
Arduino MKR WiFi 1010, Arduino MKR Vidor 4000, and Arduino UNO WiFi Rev.2.
Copyright (c) 2018 Arduino SA. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ESP32BootROM.h"
#include "SdFat.h"
#include "Adafruit_SPIFlash.h"
#if defined(ADAFRUIT_FEATHER_M4_EXPRESS) || \
defined(ADAFRUIT_FEATHER_M0_EXPRESS) || \
defined(ARDUINO_NRF52840_FEATHER) || \
defined(ADAFRUIT_ITSYBITSY_M0_EXPRESS) || \
defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
#define SerialESP32 Serial1
#define SPIWIFI SPI // The SPI port
#define SPIWIFI_SS 13 // Chip select pin
#define ESP32_RESETN 12 // Reset pin
#define SPIWIFI_ACK 11 // a.k.a BUSY or READY pin
#define ESP32_GPIO0 10
#define NEOPIXEL_PIN 8
#endif
#if defined(EXTERNAL_FLASH_USE_QSPI)
Adafruit_FlashTransport_QSPI flashTransport;
#elif defined(EXTERNAL_FLASH_USE_SPI)
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
#else
#error No QSPI/SPI flash are defined on your board variant.h !
#endif
Adafruit_SPIFlash flash(&flashTransport);
// file system object from SdFat
FatFileSystem fatfs;
static const int MAX_PAYLOAD_SIZE = 1024;
uint32_t firmsize;
static uint8_t payload[MAX_PAYLOAD_SIZE];
File myFile;
ESP32BootROMClass ESP32BootROM(SerialESP32, ESP32_GPIO0, ESP32_RESETN);
void setup() {
Serial.begin(115200);
while (!Serial);
delay(100);
Serial.print("Initializing Filesystem on external flash...");
flash.begin(); // Init external flash
Serial.print("JEDEC ID: "); Serial.println(flash.getJEDECID(), HEX);
Serial.print("Flash size: "); Serial.println(flash.size());
if (!fatfs.begin(&flash)) { // Init file system on the flash
Serial.println("FLASH init. failed!");
while (1);
}
myFile = fatfs.open("/NINA HCI BT.bin", FILE_READ);
if (!myFile) {
Serial.println("Failed to open firmware file");
while (1);
}
firmsize = myFile.size();
Serial.print(firmsize); Serial.println(" bytes");
}
void loop() {
while (!ESP32BootROM.begin(921600)) {
Serial.println("Unable to communicate with ESP32 boot ROM!");
delay(100);
return;
}
Serial.println("Ready!");
uint32_t timestamp = millis();
while (!ESP32BootROM.beginFlash(0, firmsize, MAX_PAYLOAD_SIZE)) {
Serial.println("Failed to erase flash");
delay(100);
return;
}
Serial.println("Erase OK");
for (uint32_t i=0; i<firmsize; i+=MAX_PAYLOAD_SIZE) {
memset(payload, 0xFF, MAX_PAYLOAD_SIZE);
uint32_t num_read = myFile.read(&payload, MAX_PAYLOAD_SIZE);
Serial.print("Packet #"); Serial.print(i/MAX_PAYLOAD_SIZE); Serial.print(": ");
Serial.print(num_read); Serial.print(" byte payload...");
if (!ESP32BootROM.dataFlash(payload, MAX_PAYLOAD_SIZE)) {
Serial.print("Failed to flash data");
while (1);
} else {
Serial.println("OK");
}
}
myFile.close();
uint8_t md5[16];
if (!ESP32BootROM.md5Flash(0, firmsize, md5)) {
Serial.println("Error calculating MD5");
} else {
Serial.print("MD5 OK: ");
for (int i=0; i<16; i++) {
Serial.print("0x"); Serial.print(md5[i], HEX); Serial.print(" ");
}
Serial.println();
}
Serial.print("Took "); Serial.print(millis()-timestamp); Serial.println(" millis");
while (1);
}

View file

@ -0,0 +1,61 @@
/*
Endianess.ino - Network byte order conversion functions.
Copyright (c) 2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
bool isBigEndian() {
uint32_t test = 0x11223344;
uint8_t *pTest = reinterpret_cast<uint8_t *>(&test);
return pTest[0] == 0x11;
}
uint32_t fromNetwork32(uint32_t from) {
static const bool be = isBigEndian();
if (be) {
return from;
} else {
uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
uint32_t to;
to = pFrom[0]; to <<= 8;
to |= pFrom[1]; to <<= 8;
to |= pFrom[2]; to <<= 8;
to |= pFrom[3];
return to;
}
}
uint16_t fromNetwork16(uint16_t from) {
static bool be = isBigEndian();
if (be) {
return from;
} else {
uint8_t *pFrom = reinterpret_cast<uint8_t *>(&from);
uint16_t to;
to = pFrom[0]; to <<= 8;
to |= pFrom[1];
return to;
}
}
uint32_t toNetwork32(uint32_t to) {
return fromNetwork32(to);
}
uint16_t toNetwork16(uint16_t to) {
return fromNetwork16(to);
}

View file

@ -71,8 +71,12 @@ unsigned long baud = 115200;
#define ESP32_RESETN 5 // Reset pin
#define ESP32_GPIO0 -1 // Not connected
#define NEOPIXEL_PIN 8
#elif defined(ADAFRUIT_PYPORTAL)
#endif
#if defined(ADAFRUIT_PYPORTAL)
#define NEOPIXEL_PIN 2
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
#define NEOPIXEL_PIN 40
#endif
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(1, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);

View file

@ -0,0 +1,156 @@
#include <Adafruit_APDS9960.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_LIS3MDL.h>
#include <Adafruit_LSM6DS33.h>
#include <Adafruit_SHT31.h>
#include <Adafruit_Sensor.h>
#include <PDM.h>
Adafruit_APDS9960 apds9960; // proximity, light, color, gesture
Adafruit_BMP280 bmp280; // temperautre, barometric pressure
Adafruit_LIS3MDL lis3mdl; // magnetometer
Adafruit_LSM6DS33 lsm6ds33; // accelerometer, gyroscope
Adafruit_SHT31 sht30; // humidity
uint8_t proximity;
uint16_t r, g, b, c;
float temperature, pressure, altitude;
float magnetic_x, magnetic_y, magnetic_z;
float accel_x, accel_y, accel_z;
float gyro_x, gyro_y, gyro_z;
float humidity;
int32_t mic;
extern PDMClass PDM;
short sampleBuffer[256]; // buffer to read samples into, each sample is 16-bits
volatile int samplesRead; // number of samples read
void setup(void) {
Serial.begin(115200);
// while (!Serial) delay(10);
Serial.println("Feather Sense Sensor Demo");
// initialize the sensors
apds9960.begin();
apds9960.enableProximity(true);
apds9960.enableColor(true);
bmp280.begin();
lis3mdl.begin_I2C();
lsm6ds33.begin_I2C();
sht30.begin();
PDM.onReceive(onPDMdata);
PDM.begin(1, 16000);
}
void loop(void) {
proximity = apds9960.readProximity();
while (!apds9960.colorDataReady()) {
delay(5);
}
apds9960.getColorData(&r, &g, &b, &c);
temperature = bmp280.readTemperature();
pressure = bmp280.readPressure();
altitude = bmp280.readAltitude(1013.25);
lis3mdl.read();
magnetic_x = lis3mdl.x;
magnetic_y = lis3mdl.y;
magnetic_z = lis3mdl.z;
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
lsm6ds33.getEvent(&accel, &gyro, &temp);
accel_x = accel.acceleration.x;
accel_y = accel.acceleration.y;
accel_z = accel.acceleration.z;
gyro_x = gyro.gyro.x;
gyro_y = gyro.gyro.y;
gyro_z = gyro.gyro.z;
humidity = sht30.readHumidity();
samplesRead = 0;
mic = getPDMwave(4000);
Serial.println("\nFeather Sense Sensor Demo");
Serial.println("---------------------------------------------");
Serial.print("Proximity: ");
Serial.println(apds9960.readProximity());
Serial.print("Red: ");
Serial.print(r);
Serial.print(" Green: ");
Serial.print(g);
Serial.print(" Blue :");
Serial.print(b);
Serial.print(" Clear: ");
Serial.println(c);
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" C");
Serial.print("Barometric pressure: ");
Serial.println(pressure);
Serial.print("Altitude: ");
Serial.print(altitude);
Serial.println(" m");
Serial.print("Magnetic: ");
Serial.print(magnetic_x);
Serial.print(" ");
Serial.print(magnetic_y);
Serial.print(" ");
Serial.print(magnetic_z);
Serial.println(" uTesla");
Serial.print("Acceleration: ");
Serial.print(accel_x);
Serial.print(" ");
Serial.print(accel_y);
Serial.print(" ");
Serial.print(accel_z);
Serial.println(" m/s^2");
Serial.print("Gyro: ");
Serial.print(gyro_x);
Serial.print(" ");
Serial.print(gyro_y);
Serial.print(" ");
Serial.print(gyro_z);
Serial.println(" dps");
Serial.print("Humidity: ");
Serial.print(humidity);
Serial.println(" %");
Serial.print("Mic: ");
Serial.println(mic);
delay(300);
}
/*****************************************************************/
int32_t getPDMwave(int32_t samples) {
short minwave = 30000;
short maxwave = -30000;
while (samples > 0) {
if (!samplesRead) {
yield();
continue;
}
for (int i = 0; i < samplesRead; i++) {
minwave = min(sampleBuffer[i], minwave);
maxwave = max(sampleBuffer[i], maxwave);
samples--;
}
// clear the read count
samplesRead = 0;
}
return maxwave - minwave;
}
void onPDMdata() {
// query the number of bytes available
int bytesAvailable = PDM.available();
// read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}

View file

@ -6,8 +6,11 @@ To be used with another Circuit Playground Bluefruit running the Remote Control
import board
import neopixel
from adafruit_circuitplayground.bluefruit import cpb
from adafruit_led_animation.animation import Blink, Comet, Sparkle, AnimationGroup,\
AnimationSequence
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.sparkle import Sparkle
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.sequence import AnimationSequence
import adafruit_led_animation.color as color
from adafruit_ble import BLERadio

View file

@ -0,0 +1,183 @@
# Lucio 2020
# Feather M4 + Propmaker + amps + lots of neopixels
import board
import busio
from digitalio import DigitalInOut, Direction, Pull
import audioio
import audiomixer
import audiomp3
import adafruit_lis3dh
import neopixel
from adafruit_led_animation.animation.solid import Solid
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.pulse import Pulse
from adafruit_led_animation.helper import PixelSubset
from adafruit_led_animation.group import AnimationGroup
from adafruit_led_animation.color import RED, ORANGE, WHITE
ORANGE_DIM = 0x801400 # half value version
RED_DIM = 0x800000
# ---Set Volume Max Here---
VOLUME_MULT = 0.65 # 1 = full volume, 0.1 is very quiet, 0 is muted
# ---SWITCH/BUTTON SETUP---
mode_switch = DigitalInOut(board.D9)
mode_switch.switch_to_input(pull=Pull.UP)
mode_state = mode_switch.value
trig_button = DigitalInOut(board.A4)
trig_button.switch_to_input(pull=Pull.UP)
alt_button = DigitalInOut(board.A5)
alt_button.switch_to_input(pull=Pull.UP)
# ---ACCELEROMETER SETUP---
# Set up accelerometer on I2C bus, 4G range:
i2c = busio.I2C(board.SCL, board.SDA)
int1 = DigitalInOut(board.D6)
accel = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
# ---SPEAKER SETUP---
enable = DigitalInOut(board.D10)
enable.direction = Direction.OUTPUT
enable.value = True
# Set up speakers and mixer. Stereo files, where music has empty right channel, FX empty left
speaker = audioio.AudioOut(board.A0, right_channel=board.A1)
mixer = audiomixer.Mixer(channel_count=2, buffer_size=2304, sample_rate=22050)
# ---NEOPIXEL SETUP---
pixel_pin = board.D5
pixel_num = 154
pixels = neopixel.NeoPixel(
pixel_pin, pixel_num, brightness=0.6, auto_write=False, pixel_order=neopixel.GRBW
)
# ^ change pixel_order depending on RGB vs. RGBW pixels
# ---Pixel Map---
# this is the physical order in which the strips are plugged
pixel_stripA = PixelSubset(pixels, 0, 18) # 18 pixel strip
pixel_stripB = PixelSubset(pixels, 18, 36) # 18 pixel strip
pixel_jewel = PixelSubset(pixels, 36, 43) # 7 pixel jewel
pixel_ringsAll = PixelSubset(pixels, 43, 151) # all of the rings
# or use rings individually:
# pixel_ringA = PixelSubset(pixels, 43, 59) # 16 pixel ring
# pixel_ringB = PixelSubset(pixels, 59, 75) # 16 pixel ring
# pixel_ringC = PixelSubset(pixels, 75, 91) # 16 pixel ring
# pixel_ringD = PixelSubset(pixels, 91, 151) # 60 pixel ring
# ---BPM---
BPM = 128
BEAT = 60 / BPM # quarter note beat
b16TH = BEAT / 4 # 16TH note
b64TH = BEAT / 16 # sixty-fourth
# ---Anim Setup---
# heal color mode
# Pulse 'speed' = smoothness
pulse_rings_m0 = Pulse(pixel_ringsAll, speed=0.01, color=ORANGE, period=BEAT)
pulse_jewel_m0 = Pulse(pixel_jewel, speed=0.01, color=ORANGE, period=BEAT)
comet_stripA_m0 = Comet(
pixel_stripA, speed=b64TH, color=ORANGE, tail_length=9, bounce=False
)
comet_stripB_m0 = Comet(
pixel_stripB, speed=b64TH, color=ORANGE, tail_length=9, bounce=False
)
# speed color mode
pulse_rings_m1 = Pulse(pixel_ringsAll, speed=0.02, color=RED, period=BEAT / 2)
pulse_jewel_m1 = Pulse(pixel_jewel, speed=0.02, color=RED, period=BEAT / 2)
comet_stripA_m1 = Comet(
pixel_stripA, speed=b64TH, color=RED, tail_length=9, bounce=False
)
comet_stripB_m1 = Comet(
pixel_stripB, speed=b64TH, color=RED, tail_length=9, bounce=False
)
solid_white = Solid(pixel_ringsAll, color=WHITE)
# ---Anim Modes---
vu_strip_animations_mode0 = AnimationGroup(comet_stripA_m0, comet_stripB_m0, sync=True)
vu_strip_animations_mode1 = AnimationGroup(comet_stripA_m1, comet_stripB_m1, sync=True)
# ---Audio Setup---
if mode_state:
BGM = "/lucio/bgmheal.mp3"
else:
BGM = "/lucio/bgmspeed.mp3"
sample0 = audiomp3.MP3Decoder(open(BGM, "rb"))
FX = "/lucio/shoot.mp3"
sample1 = audiomp3.MP3Decoder(open(FX, "rb"))
speaker.play(mixer)
mixer.voice[0].play(sample0, loop=True)
mixer.voice[0].level = 0.3 * VOLUME_MULT
mixer.voice[1].level = 0.7 * VOLUME_MULT
while True:
if mode_state: # heal mode on startup
vu_strip_animations_mode0.animate()
pulse_rings_m0.animate()
pulse_jewel_m0.animate()
else: # speed mode on startup
vu_strip_animations_mode1.animate()
pulse_rings_m1.animate()
pulse_jewel_m1.animate()
# Change modes
if mode_switch.value:
if mode_state == 0: # state has changed, toggle it
BGM = "/lucio/bgmheal.mp3"
sample0.file = open(BGM, "rb")
mixer.voice[0].play(sample0, loop=True)
vu_strip_animations_mode0.animate()
pulse_rings_m0.animate()
pulse_jewel_m0.animate()
mode_state = 1
else:
if mode_state == 1:
BGM = "/lucio/bgmspeed.mp3"
sample0.file = open(BGM, "rb")
mixer.voice[0].play(sample0, loop=True)
vu_strip_animations_mode1.animate()
pulse_rings_m1.animate()
pulse_jewel_m1.animate()
mode_state = 0
x, _, _ = accel.acceleration # get accelerometer values
if not mixer.voice[1].playing:
if not trig_button.value: # trigger squeezed
FX_sample = "/lucio/shoot.mp3"
sample1.file = open(FX_sample, "rb")
mixer.voice[1].play(sample1)
if mode_state:
solid_white.animate()
else:
solid_white.animate()
if not alt_button.value: # alt trigger squeezed
FX_sample = "/lucio/alt_shoot.mp3"
sample1.file = open(FX_sample, "rb")
mixer.voice[1].play(sample1)
if mode_state:
solid_white.animate()
else:
solid_white.animate()
if accel.acceleration.x > 8: # reload
FX_sample = "/lucio/reload.mp3"
sample1.file = open(FX_sample, "rb")
mixer.voice[1].play(sample1)
if mode_state:
solid_white.animate()
else:
solid_white.animate()
if accel.acceleration.x < -8: # Ultimate
FX_sample = "/lucio/ultimate.mp3"
sample1.file = open(FX_sample, "rb")
mixer.voice[1].play(sample1)
if mode_state:
solid_white.animate()
else:
solid_white.animate()

View file

@ -0,0 +1,391 @@
import time
from random import randint
from micropython import const
import board
import terminalio
import displayio
import adafruit_imageload
import digitalio
import simpleio
from gamepadshift import GamePadShift
from adafruit_display_text import label
# setup for PyBadge buttons
BUTTON_LEFT = const(128)
BUTTON_UP = const(64)
BUTTON_DOWN = const(32)
BUTTON_RIGHT = const(16)
BUTTON_SEL = const(8)
BUTTON_START = const(4)
BUTTON_A = const(2)
BUTTON_B = const(1)
pad = GamePadShift(digitalio.DigitalInOut(board.BUTTON_CLOCK),
digitalio.DigitalInOut(board.BUTTON_OUT),
digitalio.DigitalInOut(board.BUTTON_LATCH))
current_buttons = pad.get_pressed()
last_read = 0
# enables speaker
speakerEnable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speakerEnable.switch_to_output(value=True)
# Sprite cell values
EMPTY = 0
BLINKA_1 = 1
BLINKA_2 = 2
SPARKY = 3
HEART = 4
JUMP_1 = 5
JUMP_2 = 6
# creates display
display = board.DISPLAY
# scale=2 allows the sprites to be bigger
group = displayio.Group(max_size=30, scale=2)
# Blinka sprite setup
blinka, blinka_pal = adafruit_imageload.load("/spritesNew.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# creates a transparent background for Blinka
blinka_pal.make_transparent(7)
blinka_grid = displayio.TileGrid(blinka, pixel_shader=blinka_pal,
width=2, height=1,
tile_height=16, tile_width=16,
default_tile=EMPTY)
blinka_grid.x = 0
blinka_grid.y = 32
blinka_group = displayio.Group()
blinka_group.append(blinka_grid)
# first Sparky sprite
sparky0, sparky0_pal = adafruit_imageload.load("/spritesNew.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
sparky0_pal.make_transparent(7)
sparky0_grid = displayio.TileGrid(sparky0, pixel_shader=sparky0_pal,
width=1, height=1,
tile_height=16, tile_width=16,
default_tile=SPARKY)
# all Sparky sprites begin off screen
sparky0_grid.x = 100
sparky0_grid.y = 32
sparky0_group = displayio.Group()
sparky0_group.append(sparky0_grid)
# 2nd Sparky sprite
sparky1, sparky1_pal = adafruit_imageload.load("/spritesNew.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
sparky1_pal.make_transparent(7)
sparky1_grid = displayio.TileGrid(sparky1, pixel_shader=sparky1_pal,
width=1, height=1,
tile_height=16, tile_width=16,
default_tile=SPARKY)
sparky1_grid.x = 100
sparky1_grid.y = 32
sparky1_group = displayio.Group()
sparky1_group.append(sparky1_grid)
# 3rd Sparky sprite
sparky2, sparky2_pal = adafruit_imageload.load("/spritesNew.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
sparky2_pal.make_transparent(7)
sparky2_grid = displayio.TileGrid(sparky2, pixel_shader=sparky2_pal,
width=1, height=1,
tile_height=16, tile_width=16,
default_tile=SPARKY)
sparky2_grid.x = 100
sparky2_grid.y = 32
sparky2_group = displayio.Group()
sparky2_group.append(sparky2_grid)
# heart sprite group
life_bit, life_pal = adafruit_imageload.load("/spritesNew.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
life_grid = displayio.TileGrid(life_bit, pixel_shader=life_pal,
width=3, height=1,
tile_height=16, tile_width=16,
default_tile=HEART)
life_group = displayio.Group()
life_group.append(life_grid)
# adding all graphics groups to the main display group
group.append(blinka_group)
group.append(sparky0_group)
group.append(sparky1_group)
group.append(sparky2_group)
group.append(life_group)
# text area for the running score
score_text = " "
font = terminalio.FONT
score_color = 0x0000FF
# text for "game over" graphic
game_over_text = label.Label(font, text = " ", color = 0xFF00FF)
# score text
score_area = label.Label(font, text=score_text, color=score_color)
# text for "new game" graphic
new_game_text = label.Label(font, text = " ", color = 0xFF00FF)
# coordinants for text areas
score_area.x = 57
score_area.y = 6
game_over_text.x = 13
game_over_text.y = 30
new_game_text.x = 8
new_game_text.y = 30
# creating a text display group
text_group = displayio.Group()
text_group.append(score_area)
text_group.append(game_over_text)
text_group.append(new_game_text)
# adding text group to main display group
group.append(text_group)
# displaying main display group
display.show(group)
# state for hit detection
crash = False
# states to see if a Sparky is on screen
sparky0 = False
sparky1 = False
sparky2 = False
# array of Sparky states
sparky_states = [sparky0, sparky1, sparky2]
# array of x location for Sparky's
sparky_x = [sparky0_grid.x, sparky1_grid.x, sparky2_grid.x]
# function to display the heart sprites for lives
def life():
for _ in range(0, 3):
life_grid[_, 0] = EMPTY
for hearts in range(life_count):
life_grid[hearts, 0] = HEART
# lives at beginning of the game
life_count = 3
# variables for scoring
jump_score = 0
total_score = 0
bonus = 0
# state for Blinka being in default 'slither' mode
snake = True
# state to check if Blinka has jumped over Sparky
cleared = False
# state for the end of a game
end = False
# state for a new game beginning
new_game = True
# state for detecting game over
game_over = False
# variable to change between Blinka's two slither sprites
b = 1
# variable to hold time.monotonic() count for Blinka slither animation
slither = 0
# variables to hold time.monotonic() count to delay Sparky spawning
blue = 0
smoke = 0
monster = 0
while True:
# checks if button has been pressed
if (last_read + 0.01) < time.monotonic():
buttons = pad.get_pressed()
last_read = time.monotonic()
# new game
if new_game and not game_over:
# graphics for new game splash screen
blinka_grid.y = 16
blinka_grid[0] = JUMP_1
blinka_grid[1] = JUMP_2
sparky0_grid.x = 5
sparky1_grid.x = 40
sparky2_grid.x = 65
score_area.text = 300
new_game_text.text = "BLINKA JUMP"
life()
# if start is pressed...
if current_buttons != buttons:
if buttons & BUTTON_START:
# prepares display for gameplay
print("start game")
new_game_text.text = " "
life_count = 3
start = time.monotonic()
new_game = False
end = False
sparky0_grid.x = 100
sparky1_grid.x = 100
sparky2_grid.x = 100
# if game has started...
if not game_over and not new_game:
# gets time.monotonic() to have a running score
mono = time.monotonic()
score = mono - start
# adds 10 points every time a Sparky is cleared
total_score = score + jump_score
# displays score as text
score_area.text = int(total_score)
# puts Sparky states and x location into callable arrays
for s in range(3):
sparky_state = sparky_states[s]
sparky_location = sparky_x[s]
# Sparkys are generated using a staggered delay
# and matching an int to a random int
# 1st Sparky
if (blue + 0.03) < time.monotonic():
if randint(1, 15) == 3:
sparky_states[0] = True
blue = time.monotonic()
# 2nd Sparky
if (smoke + 0.07) < time.monotonic():
if randint(1, 15) == 7:
sparky_states[1] = True
smoke = time.monotonic()
# 3rd Sparky
if (monster + 0.12) < time.monotonic():
if randint(1, 15) == 12:
sparky_states[2] = True
monster = time.monotonic()
# if a Sparky is generated, it scrolls across the screen 1 pixel at a time
# 1st Sparky
if sparky_states[0] is True:
sparky0_grid.x -= 1
sparky_x[0] = sparky0_grid.x
display.refresh(target_frames_per_second=120)
# when a Sparky is 16 pixels off the display,
# it goes back to its starting position
if sparky0_grid.x is -16:
sparky_states[0] = False
sparky0_grid.x = 100
sparky_x[0] = sparky0_grid.x
# 2nd Sparky
if sparky_states[1] is True:
sparky1_grid.x -= 1
sparky_x[1] = sparky1_grid.x
display.refresh(target_frames_per_second=120)
if sparky1_grid.x is -16:
sparky_states[1] = False
sparky1_grid.x = 100
sparky_x[1] = sparky1_grid.x
# 3rd Sparky
if sparky_states[2] is True:
sparky2_grid.x -= 1
sparky_x[2] = sparky2_grid.x
display.refresh(target_frames_per_second=120)
if sparky2_grid.x is -16:
sparky_states[2] = False
sparky2_grid.x = 100
sparky_x[2] = sparky2_grid.x
# if no lives are left then the game ends
if life_count is 0:
game_over = True
# if the A button is pressed then Blinka is no longer in the default
# slither animation aka she jumps
if current_buttons != buttons:
if buttons & BUTTON_A:
snake = False
# heart sprites are displayed to show life count
life()
# if Blinka is slithering...
if snake:
# Blinka default location
blinka_grid.y = 32
# empty 2nd tile so that the jump sprite can be shown using
# the same tilegrid
blinka_grid[1] = EMPTY
# every .15 seconds Blinka's slither sprite changes
# so that her slithering is animated
# b holds tilegrid position to display correct sprite
if (slither + 0.15) < time.monotonic():
blinka_grid[0] = b
b += 1
slither = time.monotonic()
if b > 2:
b = 1
# if a Sparky collides with Blinka while she is slithering...
for s in range(3):
if sparky_x[s] == 8 and blinka_grid.y == 32:
# tone is played
simpleio.tone(board.SPEAKER, 493.88, 0.05)
simpleio.tone(board.SPEAKER, 349.23, 0.05)
# lose a life
life_count = life_count - 1
# if the A button is pressed then...
else:
# Blinka JUMPS
# y location changes one row up and both jump sprites are shown
blinka_grid.y = 16
blinka_grid[0] = JUMP_1
blinka_grid[1] = JUMP_2
# if Blinka jumps over a Sparky...
for j in range(3):
if sparky_x[j] == 8 and not cleared:
# 10 points to the player
bonus += 1
jump_score = bonus * 10
cleared = True
# special victory tone is played
simpleio.tone(board.SPEAKER, 523.25, 0.005)
simpleio.tone(board.SPEAKER, 783.99, 0.005)
# resets back to Blinka animation
snake = True
# resets that Blinka has not jumped over a Sparky
cleared = False
# if there are no more lives, the game is over
if game_over and not new_game:
# game over text is displayed
game_over_text.text = "GAME OVER"
score_area.text = " "
# end game tone is played
# and then the screen holds with the last
# sprites on screen and game over text
if not end:
simpleio.tone(board.SPEAKER, 220, 0.05)
simpleio.tone(board.SPEAKER, 207.65, 0.05)
simpleio.tone(board.SPEAKER, 196, 0.5)
end = True
# if the start button is pressed...
if (current_buttons != buttons) and game_over:
if buttons & BUTTON_START:
# display, states and score are reset for gameplay
game_over_text.text = " "
life_count = 3
start = time.monotonic()
game_over = False
end = False
total_score = 0
jump_score = 0
bonus = 0
score = 0
blue = 0
smoke = 0
monster = 0
sparky0_grid.x = 100
sparky1_grid.x = 100
sparky2_grid.x = 100
# game begins again with all Sparky's off screen

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -15,7 +15,7 @@ import neopixel
from adafruit_esp32spi import adafruit_esp32spi
from adafruit_esp32spi import adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
import adafruit_minimqtt as MQTT
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_aws_iot import MQTT_CLIENT
from adafruit_seesaw.seesaw import Seesaw
import aws_gfx_helper

View file

@ -15,7 +15,7 @@ import neopixel
from adafruit_esp32spi import adafruit_esp32spi, adafruit_esp32spi_wifimanager
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_gc_iot_core import MQTT_API, Cloud_Core
import adafruit_minimqtt as MQTT
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_seesaw.seesaw import Seesaw
import digitalio

View file

@ -0,0 +1,148 @@
import random
import time
import adafruit_imageload.bmp
import audioio
import audiomp3
import board
import displayio
import digitalio
import framebufferio
import rgbmatrix
displayio.release_displays()
matrix = rgbmatrix.RGBMatrix(
width=64, height=32, bit_depth=4,
rgb_pins=[board.D6, board.D5, board.D9, board.D11, board.D10, board.D12],
addr_pins=[board.A5, board.A4, board.A3, board.A2],
clock_pin=board.D13, latch_pin=board.D0, output_enable_pin=board.D1)
display = framebufferio.FramebufferDisplay(matrix, auto_refresh=False)
# Each wheel can be in one of three states:
STOPPED, RUNNING, BRAKING = range(3)
# Return a duplicate of the input list in a random (shuffled) order.
def shuffled(seq):
return sorted(seq, key=lambda _: random.random())
# The Wheel class manages the state of one wheel. "pos" is a position in
# floating point coordinates, with one 1 pixel being 1 position.
# The wheel also has a velocity (in positions
# per tick) and a state (one of the above constants)
class Wheel(displayio.TileGrid):
def __init__(self, bitmap, palette):
# Portions of up to 3 tiles are visible.
super().__init__(bitmap=bitmap, pixel_shader=palette,
width=1, height=3, tile_width=20, tile_height=24)
self.order = shuffled(range(20))
self.state = STOPPED
self.pos = 0
self.vel = 0
self.termvel = 2
self.y = 0
self.x = 0
self.stop_time = time.monotonic_ns()
self.step()
def step(self):
# Update each wheel for one time step
if self.state == RUNNING:
# Slowly lose speed when running, but go at least terminal velocity
self.vel = max(self.vel * .99, self.termvel)
if time.monotonic_ns() > self.stop_time:
self.state = BRAKING
elif self.state == BRAKING:
# More quickly lose speed when baking, down to speed 0.4
self.vel = max(self.vel * .85, 0.4)
# Advance the wheel according to the velocity, and wrap it around
# after 24*20 positions
self.pos = (self.pos + self.vel) % (20*24)
# Compute the rounded Y coordinate
yy = round(self.pos)
# Compute the offset of the tile (tiles are 24 pixels tall)
yyy = yy % 24
# Find out which tile is the top tile
off = yy // 24
# If we're braking and a tile is close to midscreen,
# then stop and make sure that tile is exactly centered
if self.state == BRAKING and self.vel <= 2 and yyy < 8:
self.pos = off * 24
self.vel = 0
yyy = 0
self.state = STOPPED
# Move the displayed tiles to the correct height and make sure the
# correct tiles are displayed.
self.y = yyy - 20
for i in range(3):
self[i] = self.order[(19 - i + off) % 20]
# Set the wheel running again, using a slight bit of randomness.
# The 'i' value makes sure the first wheel brakes first, the second
# brakes second, and the third brakes third.
def kick(self, i):
self.state = RUNNING
self.vel = random.uniform(8, 10)
self.termvel = random.uniform(1.8, 4.2)
self.stop_time = time.monotonic_ns() + 3000000000 + i * 350000000
# This bitmap contains the emoji we're going to use. It is assumed
# to contain 20 icons, each 20x24 pixels. This fits nicely on the 64x32
# RGB matrix display.
the_bitmap, the_palette = adafruit_imageload.load(
"/emoji.bmp",
bitmap=displayio.Bitmap,
palette=displayio.Palette)
# Our fruit machine has 3 wheels, let's create them with a correct horizontal
# (x) offset and arbitrary vertical (y) offset.
g = displayio.Group(max_size=3)
wheels = []
for idx in range(3):
wheel = Wheel(the_bitmap, the_palette)
wheel.x = idx * 22
wheel.y = -20
g.append(wheel)
wheels.append(wheel)
display.show(g)
# We want a digital input to trigger the fruit machine
button = digitalio.DigitalInOut(board.A1)
button.switch_to_input(pull=digitalio.Pull.UP)
# Enable the speaker
enable = digitalio.DigitalInOut(board.D4)
enable.switch_to_output(True)
mp3file = open("/triangles-loop.mp3", "rb")
sample = audiomp3.MP3Decoder(mp3file)
# Play the sample (just loop it for now)
speaker = audioio.AudioOut(board.A0)
speaker.play(sample, loop=True)
# Here's the main loop
while True:
# Refresh the dislpay (doing this manually ensures the wheels move
# together, not at different times)
display.refresh(minimum_frames_per_second=0, target_frames_per_second=60)
all_stopped = all(si.state == STOPPED for si in wheels)
if all_stopped:
# Once everything comes to a stop, wait until the lever is pulled and
# start everything over again. Maybe you want to check if the
# combination is a "winner" and add a light show or something.
while button.value:
pass
for idx, si in enumerate(wheels):
si.kick(idx)
# Otherwise, let the wheels keep spinning...
for idx, si in enumerate(wheels):
si.step()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

View file

@ -1,5 +1,9 @@
// Basic demo for accelerometer, gyro, and magnetometer readings from the Adafruit
// LSM6DSOX+LIS3MDL Breakout or FeatherWing and the LSM6DSOX+LIS3MDL Breakout
// Basic demo for accelerometer, gyro, and magnetometer readings
// from the following Adafruit ST Sensor combo boards:
// * LSM6DSOX + LIS3MDL FeatherWing : https://www.adafruit.com/product/4565
// * ISM330DHCX + LIS3MDL FeatherWing https://www.adafruit.com/product/4569
// * LSM6DSOX + LIS3MDL Breakout : https://www.adafruit.com/product/4517
// * LSM6DS33 + LIS3MDL Breakout Lhttps://www.adafruit.com/product/4485
#include <Adafruit_LSM6DSOX.h>
Adafruit_LSM6DSOX lsm6ds;
@ -9,8 +13,12 @@ Adafruit_LSM6DSOX lsm6ds;
//#include <Adafruit_LSM6DS33.h>
//Adafruit_LSM6DS33 lsm6ds;
#include <Adafruit_LIS3MDL.h>
// To use with the ISM330DHCX+LIS3MDL Feather Wing, uncomment these two lines
// and comment out the lines referring to the LSM6DSOX above
//#include <Adafruit_ISM330DHCX.h>
//Adafruit_ISM330DHCX lsm6ds;
#include <Adafruit_LIS3MDL.h>
Adafruit_LIS3MDL lis3mdl;
void setup(void) {
@ -114,8 +122,9 @@ void setup(void) {
case LSM6DS_GYRO_RANGE_2000_DPS:
Serial.println("2000 degrees/s");
break;
case ISM330DHCT_GYRO_RANGE_4000_DPS:
break; // unsupported range for the DSOX
case ISM330DHCX_GYRO_RANGE_4000_DPS:
Serial.println("4000 degrees/s");
break;
}
// lsm6ds.setGyroDataRate(LSM6DS_RATE_12_5_HZ);
Serial.print("Gyro data rate set to: ");

View file

@ -1 +1 @@
depends=Adafruit ILI9341, Adafruit BusIO, SD, Adafruit NeoPixel, Adafruit VS1053 Library, Adafruit BluefruitLE nRF51, Adafruit seesaw Library, Ethernet, Adafruit IO Arduino, Adafruit LSM303, FastLED, Adafruit LiquidCrystal, Adafruit SoftServo, TinyWireM, Adafruit AM radio library, WaveHC, Adafruit LED Backpack Library, MAX31850 OneWire, Adafruit VC0706 Serial Camera Library, RTClib, Adafruit SleepyDog Library, Adafruit Thermal Printer Library, Adafruit Zero I2S Library, Adafruit EPD, Adafruit SSD1351 library, Adafruit FONA Library, Adafruit Motor Shield V2 Library, Adafruit NeoMatrix, Adafruit Soundboard library, Adafruit Circuit Playground, MIDI, ArduinoJson, Adafruit TCS34725, Adafruit Pixie, Adafruit GPS Library, TinyGPS, WiFi101, Adafruit DotStar, Adafruit Si7021 Library, Adafruit WS2801 Library, Mouse, Keyboard, Time, IRremote, Adafruit LSM9DS0 Library, Adafruit Arcada Library, MIDIUSB, PubSubClient, Adafruit LIS2MDL, Adafruit NeoPXL8, Adafruit MCP23017 Arduino Library, Adafruit MLX90640, LiquidCrystal, Adafruit NeoTrellis M4 Library, RGB matrix Panel, Adafruit MLX90614 Library, Adafruit RGB LCD Shield Library, MAX6675 library, Adafruit MP3, Adafruit Keypad, Adafruit Arcada GifDecoder, Keypad, Neosegment, Encoder, Adafruit TiCoServo, Adafruit Trellis Library, FauxmoESP, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, CapacitiveSensor, Adafruit Zero PDM Library, Adafruit DMA neopixel library, elapsedMillis, DST RTC
depends=Adafruit ILI9341, Adafruit BusIO, SD, Adafruit NeoPixel, Adafruit VS1053 Library, Adafruit BluefruitLE nRF51, Adafruit seesaw Library, Ethernet, Adafruit IO Arduino, FastLED, Adafruit LiquidCrystal, Adafruit SoftServo, TinyWireM, Adafruit AM radio library, WaveHC, Adafruit LED Backpack Library, MAX31850 OneWire, Adafruit VC0706 Serial Camera Library, RTClib, Adafruit SleepyDog Library, Adafruit Thermal Printer Library, Adafruit Zero I2S Library, Adafruit EPD, Adafruit SSD1351 library, Adafruit FONA Library, Adafruit Motor Shield V2 Library, Adafruit NeoMatrix, Adafruit Soundboard library, Adafruit Circuit Playground, ArduinoJson, Adafruit TCS34725, Adafruit Pixie, Adafruit GPS Library, TinyGPS, WiFi101, Adafruit DotStar, Adafruit Si7021 Library, Adafruit WS2801 Library, Mouse, Keyboard, Time, IRremote, Adafruit LSM9DS0 Library, Adafruit Arcada Library, MIDIUSB, PubSubClient, Adafruit LIS2MDL, Adafruit NeoPXL8, Adafruit MCP23017 Arduino Library, Adafruit MLX90640, LiquidCrystal, Adafruit NeoTrellis M4 Library, RGB matrix Panel, Adafruit MLX90614 Library, Adafruit RGB LCD Shield Library, MAX6675 library, Adafruit MP3, Adafruit Keypad, Adafruit Arcada GifDecoder, Keypad, Neosegment, Encoder, Adafruit TiCoServo, Adafruit Trellis Library, FauxmoESP, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, CapacitiveSensor, Adafruit Zero PDM Library, Adafruit DMA neopixel library, elapsedMillis, DST RTC

View file

@ -11,7 +11,7 @@ import neopixel
from adafruit_bitmap_font import bitmap_font
from adafruit_display_text.label import Label
from adafruit_io.adafruit_io import IO_MQTT
import adafruit_minimqtt as MQTT
import adafruit_minimqtt.adafruit_minimqtt as MQTT
from adafruit_pyportal import PyPortal
from adafruit_seesaw.seesaw import Seesaw
from simpleio import map_range